对websocket的理解
websocket,也是应用层的网络通信协议,要理解它是什么,就要问为什么会出现这个协议。
在没有websocket以前,我们都是用http协议做数据收发,渐渐的,我们发现有一些场景http的特性无法很好地处理。例如,服务端想主动发送给客户端信息的时候怎么办?如果用http来处理这个场景,就涉及到客户端方面的轮询。
但是轮询的逻辑是按照一定的频率,客户端不断地发送请求包,去看服务端是否"有话对我们说"。
这带来了两个主要的问题:
第一,服务端何时发送数据是不确定的,长时间持续地发送请求查询,其中大量的请求是无效的,网络利用率低下。
第二,对于需要实时发送的信息,轮询只能周期性地获取,如果服务端想要发送信息,需要等到下一个轮询周期才可以,会造成信息的延迟。如果是在线游戏,视频聊天什么的,用户当天就会打个差评再卸载掉。
所以,关键是要做到当服务端想发送的时候,就立刻主动地发送信息。
而websocket就能达成这一功能,它的特性是全双工通信 ,此外还有低延迟,数据包传输效率高的特性。这些特性都是相较于http协议来说的,你可以这么认为,想要专门应对需要高效全双工交互的应用场景,但http表示臣妾做不到啊,所以你新纳一个嫔妃websocket,专门帮你干这些活儿。
如果之前除了http协议以外没有接触过应用层协议,那么一开始是难以接受websocket概念的。为了更好地理解,需要跟http做一些关键的对比。
- http是请求-响应模式,必须要有请求,才有回复(且服务端不能主动请求)。websocket是全双工通信的,有信息就主动传达给对方。
- http短连接(一次来回后就默认关闭连接)。websocket是长连接。
- http是无状态。websocket是有状态的。
websocket是如何工作的
- 发出连接请求,客户端发送的第一个请求,是一个http请求,与普通http不同的是
arduino
Upgrade: websocket // upgrade是一个http标准头部,指定希望升级到的协议
Connection: Upgrade // connection设定完成协议升级后是否保持连接
- 服务器同意握手的响应
arduino
Upgrade: websocket // 确认升级到 WebSocket
Connection: Upgrade // 核心:确认连接已升级
- 通信阶段
核心报文数据:
- FIN:是否是结束帧,FIN=0表示还有后续,FIN=1表示是最后一个数据帧
- Opcode:帧类型,数据类型(即这个数据包是干什么的)

- Mask,是否掩码,1表示是掩码,掩码是将数据报文内容转换,而非是加密
- 连接关闭
一端发送关闭帧,另一端接受到关闭帧后,发送响应关闭帧。对话之后TCP断连。
代码实现一下websocket
现在通过java的方式来写一个websocket案例。
纯websocket的实现:
javascript
<--依赖包-->
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.4</version>
</dependency>
typescript
public class WebsocketChatRoom extends WebSocketServer {
public WebsocketChatRoom(int port) {
super(new InetSocketAddress(port));
}
@Override
public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
System.out.println("新连接到达:"+ webSocket.getRemoteSocketAddress());
}
@Override
public void onClose(WebSocket webSocket, int i, String s, boolean b) {
System.out.println("连接关闭:" + webSocket.getRemoteSocketAddress());
}
@Override
public void onMessage(WebSocket webSocket, String s) {
System.out.println("收到信息:" + s);
// websocketServer自带的广播实现
broadcast(s);
}
@Override
public void onError(WebSocket webSocket, Exception e) {
System.out.println("连接错误: "+e.getMessage());
}
@Override
public void onStart() {
}
public static void main(String[] args) {
int port = 8888;
WebsocketChatRoom server = new WebsocketChatRoom(port);
server.start();
System.out.println("聊天室,启动!: " + port);
}
}
上述的重点是继承WebSocketServer,它定义多个接口,每个接口望文生义,即各自连接阶段做的事情。最重要的是onMessage,参数为连接信息和报文文本。
作为后端开发,我们再请出deepseek大神帮我们写一个前端聊天窗口。

重要的是前端连接逻辑:
ini
// 创建连接
socket = new WebSocket(serverUrl);
// websocket各阶段的处理器
socket.onopen = (event) => {
console.log('WebSocket connection opened:', event);
statusIndicator.className = 'status-indicator connected';
statusText.textContent = 'Connected to server';
sendButton.disabled = false;
// Add connection message to chat
addMessage('System', 'Connected to the WebSocket server', 'received');
};
socket.onmessage = (event) => {
console.log('Message from server:', event.data);
addMessage('Server', event.data, 'received');
// Auto-scroll to bottom
chatBox.scrollTop = chatBox.scrollHeight;
};
socket.onclose = (event) => {
console.log('WebSocket connection closed:', event);
statusIndicator.className = 'status-indicator';
statusText.textContent = 'Disconnected from server';
sendButton.disabled = true;
// Add disconnection message to chat
addMessage('System', 'Disconnected from the server', 'received');
// Try to reconnect after 5 seconds
setTimeout(() => {
if (!socket || socket.readyState === WebSocket.CLOSED) {
statusText.textContent = 'Reconnecting...';
initWebSocket();
}
}, 5000);
};
socket.onerror = (error) => {
console.error('WebSocket error:', error);
statusText.textContent = 'Connection error';
sendButton.disabled = true;
};

打开两个窗口,打开时会创建自己的用户名,然后在聊天室发送信息,即可同步信息了。