2024-08-08



<!DOCTYPE html>
<html>
<head>
    <title>WebSocket 基础使用</title>
    <script type="text/javascript">
    function init() {
        output = document.getElementById('output');
        output.innerHTML = '连接中...';
        
        // 创建WebSocket实例,指定服务器地址和端口
        ws = new WebSocket('ws://localhost:8181');
        
        // 监听WebSocket的打开事件
        ws.onopen = function(evt) { 
            output.innerHTML = '已连接'; 
        };
        
        // 监听WebSocket的消息事件
        ws.onmessage = function(evt) {
            output.innerHTML += '<br>收到消息: ' + evt.data;
        };
        
        // 监听WebSocket的错误事件
        ws.onerror = function(evt) {
            output.innerHTML += '<br>发生错误'; 
        };
        
        // 监听WebSocket的关闭事件
        ws.onclose = function(evt) {
            output.innerHTML += '<br>连接已关闭'; 
        };
    }
    
    // 发送消息的函数
    function sendMessage() {
        var message = document.getElementById('message').value;
        ws.send(message);
    }
    </script>
</head>
<body onload="init();">
    <h1>WebSocket 实例</h1>
    <div id="output"></div>
    <input type="text" id="message" value="Hello, WebSocket!">
    <button onclick="sendMessage()">发送消息</button>
</body>
</html>

这段代码展示了如何在一个HTML页面中使用JavaScript来初始化一个WebSocket连接,并且提供了简单的接口来发送和接收消息。代码中包含了对WebSocket生命周期中常见事件的监听和处理:打开、接收消息、错误以及关闭连接。

2024-08-08



const WebSocket = require('ws');
 
// 创建WebSocket服务器实例,监听端口3000
const wss = new WebSocket.Server({ port: 3000 });
 
wss.on('connection', function connection(ws) {
  // 当客户端发送消息时触发
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
 
    // 将接收到的消息发送回客户端
    ws.send('something');
  });
 
  // 当WebSocket连接关闭时触发
  ws.on('close', function close() {
    console.log('disconnected');
  });
 
  // 当出现错误时触发
  ws.on('error', function error(e) {
    console.log('error: %s', e);
  });
});
 
console.log('WebSocket server is running on ws://localhost:3000');

这段代码创建了一个WebSocket服务器,监听3000端口。当有客户端连接时,它会打印出连接信息,并将接收到的消息回传给客户端。同时,它还处理了关闭事件和错误事件。这个例子简单直观地展示了如何使用ws模块创建一个基本的WebSocket服务器。

2024-08-08



@Component
public class WebSocketServer {
 
    private static final Logger log = LoggerFactory.Logger(WebSocketServer.class);
 
    private final SimpMessagingTemplate template;
 
    @Autowired
    public WebSocketServer(SimpMessagingTemplate template) {
        this.template = template;
    }
 
    // 发送消息到前端
    public void sendMessageToClient(String destination, Object payload) {
        log.info("Send message to client: " + payload);
        template.convertAndSend(destination, payload);
    }
 
    // 心跳检测逻辑
    @Scheduled(fixedRate = 30000)
    public void checkAlive() {
        log.info("Check WebSocket sessions alive...");
        // 这里添加具体的检测逻辑
    }
}

这个简化版的代码示例展示了如何在Spring Boot应用中使用SimpMessagingTemplate发送WebSocket消息,并且使用@Scheduled注解实现心跳机制。在实际应用中,你需要根据具体的WebSocket实现和业务需求来完善checkAlive方法的内部逻辑。

2024-08-07

在Node.js中,可以使用ws模块来实现WebSocket服务器。以下是一个简单的例子:

首先,通过npm安装ws模块:




npm install ws

然后,使用以下代码创建一个简单的WebSocket服务器:




const WebSocket = require('ws');
 
// 创建WebSocket服务器实例,监听端口3000
const wss = new WebSocket.Server({ port: 3000 });
 
wss.on('connection', function connection(ws) {
  // 当客户端连接时触发
 
  ws.on('message', function incoming(message) {
    // 当服务器接收到客户端发来的消息时触发
    console.log('received: %s', message);
  });
 
  // 发送消息给客户端
  ws.send('something');
});
 
console.log('WebSocket server is running on ws://localhost:3000');

运行上述代码后,你将有一个运行中的WebSocket服务器监听3000端口。任何连接到这个端口的客户端都将与服务器进行WebSocket通信。

2024-08-07

在2024年金九银十期间,WebSocket协议可能会有更新,但是关于opcode=9的解释在当前的RFC6455(WebSocket协议的第一个版本)和后续的RFC7936(对RFC6455的补充,主要是引入了压缩机制)中并没有明确的定义。

然而,根据我的知识更新日期到2023年为止的研究,opcode=9可能代表了一种预留的操作码,可能在未来的扩展中使用,或者是一个错误的操作码。

如果你在代码中遇到了一个操作码为9的WebSocket帧,你应该通知客户端这是一个不支持的操作码,并关闭连接。

以下是一个简单的处理未知操作码的示例代码(使用Go语言):




package main
 
import (
    "fmt"
    "net/http"
 
    "github.com/gorilla/websocket"
)
 
var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true // 在生产环境中应该做更严格的源检查
    },
}
 
func handleConnections(w http.ResponseWriter, r *http.Request) {
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer ws.Close()
 
    for {
        _, message, err := ws.ReadMessage()
        if err != nil {
            fmt.Println(err)
            break
        }
 
        if ws.Subprotocol() != "binary" {
            err := ws.WriteControl(websocket.CloseProtocol, []byte{}, time.Now().Add(time.Second))
            if err != nil {
                fmt.Println(err)
            }
            break
        }
 
        err = ws.WriteMessage(websocket.TextMessage, message)
        if err != nil {
            fmt.Println(err)
            break
        }
    }
}
 
func main() {
    http.HandleFunc("/", handleConnections)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        fmt.Println(err)
        return
    }
}

在这个示例中,我们首先通过upgrader.Upgrade函数将HTTP连接升级为WebSocket连接。然后,我们在一个无限循环中读取客户端发送的消息。如果读取到的操作码为9,我们通过ws.WriteControl函数向客户端发送一个关闭连接的控制帧,其中包含一个合适的关闭原因(在这个例子中是CloseProtocol)。

请注意,这个代码只是一个简单的示例,并不包括生产环境中应有的错误处理和安全措施。在实际应用中,你应该根据具体需求来调整和增强这个示例代码。

2024-08-07



<template>
  <div>
    <button @click="connect">连接</button>
    <button @click="disconnect">断开连接</button>
    <button @click="sendMessage">发送消息</button>
  </div>
</template>
 
<script>
import SockJS from 'sockjs-client';
import Stomp from 'webstomp-client';
 
export default {
  data() {
    return {
      stompClient: null,
    };
  },
  methods: {
    connect() {
      const socket = new SockJS('http://localhost:8080/endpoint-websocket');
      this.stompClient = Stomp.over(socket);
      this.stompClient.connect({}, frame => {
        console.log('Connected: ' + frame);
        this.stompClient.subscribe('/topic/greetings', message => {
          // 处理接收到的消息
          console.log(JSON.parse(message.body).content);
        });
      });
    },
    disconnect() {
      if (this.stompClient) {
        this.stompClient.disconnect();
      }
    },
    sendMessage() {
      if (this.stompClient) {
        const msg = { 'name': "John" };
        this.stompClient.send('/app/hello', JSON.stringify(msg), {});
      }
    }
  }
};
</script>

这个代码实例展示了如何在Vue.js应用中使用Stompjs和WebSocket建立连接、订阅消息、发送消息和断开连接。注意,这里假设你已经有一个运行的WebSocket服务端点,例如:http://localhost:8080/endpoint-websocket。同时,这个例子中的连接参数和订阅的目的地(例如:'/topic/greetings'和'/app/hello')需要根据实际的WebSocket服务进行相应的修改。

2024-08-07



# 导入必要的模块
import json
from channels.generic.websocket import AsyncWebsocketConsumer
 
class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        # 当WebSocket连接建立时调用
        self.room_group_name = 'chat_room'
        # 将用户加入到房间
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        await self.accept()
 
    async def disconnect(self, close_code):
        # 当WebSocket连接断开时调用
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )
 
    async def receive(self, text_data):
        # 当接收到前端发送的消息时调用
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
 
        # 广播消息到房间内所有的用户
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )
 
    async def chat_message(self, event):
        # 处理群组消息
        message = event['message']
 
        # 发送消息到WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))

这个示例代码展示了如何使用Django Channels框架来创建一个简单的WebSocket聊天服务器端。它定义了一个ChatConsumer类,用于处理WebSocket连接、断开连接和接收消息。当有新的消息发送到房间时,它会广播给该房间内的所有用户。这是一个典型的使用WebSocket进行实时通信的场景。

2024-08-07



@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
 
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
 
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableStompBrokerRelay("/topic", "/queue")
              .setRelayHost("localhost")
              .setRelayPort(61613)
              .setClientLogin("guest")
              .setClientPasscode("guest");
        config.setApplicationDestinationPrefixes("/app");
        config.setUserDestinationPrefix("/user");
    }
 
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").withSockJS();
    }
 
    @Override
    public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
        // 配置消息转换器,可以自定义消息格式
        return false;
    }
 
    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration registry) {
        registry.setSendTimeLimit(15000)
                .setSendBufferSizeLimit(512)
                .setMessageSizeLimit(1024);
    }
 
    @Bean
    public RedisBrokerMessageHandler redisBrokerMessageHandler() {
        RedisBrokerMessageHandler handler = new RedisBrokerMessageHandler(redisConnectionFactory());
        handler.setGenerateId(true);
        handler.setSystemPrefix("ws_");
        handler.setApplicationEventPublisher(applicationContext);
        return handler;
    }
 
    @Bean
    public MessageChannel clientInboundChannel() {
        return new DirectChannel();
    }
 
    @Bean
    public MessageChannel clientOutboundChannel() {
        return new DirectChannel();
    }
 
    @Bean
    public SimpleBrokerMessageHandler brokerMessageHandler(SubscribableChannel brokerChannel) {
        SimpleBrokerMessageHandler handler = new SimpleBrokerMessageHandler(clientInboundChannel());
        handler.setOrder(1);
        return handler;
    }
}

这个代码实例展示了如何配置Spring WebSocket消息代理以使用Redis作为中继,实现分布式WebSocket通信。代码中定义了消息代理的配置、STOMP端点的注册以及消息转换器和WebSocket传输的配置。同时,还提供了RedisBrokerMessageHandler和两个MessageChannel的Bean配置,这些是实现基于Redis的Ws服务必不可少的组件。

2024-08-07

在Vue中使用WebSocket,你可以创建一个Vue实例,并在其中设置WebSocket的连接和处理逻辑。以下是一个简单的例子:




<template>
  <div>
    <button @click="connectWebSocket">连接WebSocket</button>
    <button @click="sendMessage">发送消息</button>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      ws: null, // WebSocket实例
    };
  },
  methods: {
    connectWebSocket() {
      // 假设WebSocket服务器地址是 'ws://localhost:8080'
      this.ws = new WebSocket('ws://localhost:8080');
 
      this.ws.onopen = () => {
        console.log('WebSocket 连接成功');
      };
 
      this.ws.onmessage = (message) => {
        console.log('收到消息:', message.data);
      };
 
      this.ws.onerror = (error) => {
        console.error('WebSocket 出错:', error);
      };
 
      this.ws.onclose = () => {
        console.log('WebSocket 连接关闭');
      };
    },
    sendMessage() {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        this.ws.send('你好,这是一条消息!');
      } else {
        console.log('WebSocket 连接未建立,无法发送消息');
      }
    }
  }
};
</script>

在这个例子中,我们定义了一个Vue组件,其中包含了连接WebSocket服务器的方法connectWebSocket和发送消息的方法sendMessageconnectWebSocket方法创建了一个新的WebSocket实例,并设置了打开、消息接收、错误和关闭连接时的回调函数。sendMessage方法检查WebSocket连接是否已经建立,然后发送一个文本消息。

2024-08-07

在Vue 3中使用WebSocket可以通过创建一个WebSocket实例并在组件的setup函数中管理它来实现。以下是一个简单的例子:




<template>
  <div>
    <button @click="connect">Connect</button>
    <button @click="sendMessage" :disabled="!socket.readyState">Send</button>
    <button @click="disconnect" :disabled="!socket.readyState">Disconnect</button>
    <div>
      Status: {{ socket.readyState }}
    </div>
    <div>
      Messages:
      <ul>
        <li v-for="message in messages" :key="message">{{ message }}</li>
      </ul>
    </div>
  </div>
</template>
 
<script>
import { ref } from 'vue';
 
export default {
  setup() {
    const socket = ref(null);
    const messages = ref([]);
 
    function connect() {
      socket.value = new WebSocket('wss://your-websocket-server');
 
      socket.value.onopen = function(event) {
        console.log('WebSocket connected: ', event);
      };
 
      socket.value.onerror = function(error) {
        console.error('WebSocket error: ', error);
      };
 
      socket.value.onmessage = function(event) {
        messages.value.push(event.data);
      };
 
      socket.value.onclose = function() {
        console.log('WebSocket disconnected');
      };
    }
 
    function sendMessage() {
      if (socket.value && socket.value.readyState === WebSocket.OPEN) {
        socket.value.send('Your message here');
      }
    }
 
    function disconnect() {
      if (socket.value) {
        socket.value.close();
        socket.value = null;
      }
    }
 
    return {
      socket,
      messages,
      connect,
      sendMessage,
      disconnect
    };
  }
};
</script>

在这个例子中,我们创建了一个WebSocket连接,并在组件的setup函数中定义了连接、发送消息和断开连接的方法。我们还监听了WebSocket的打开、错误、接收消息和关闭事件,并将它们与Vue响应式数据(messages数组和socket实例)相关联。

请确保将'wss://your-websocket-server'替换为您的WebSocket服务器地址。此外,这里的WebSocket URL使用的是wss协议,如果您的服务器支持ws(非加密的WebSocket),您也可以使用'ws://your-websocket-server'