最近在尝试仿造微信,用到了即时通讯这方面的知识,显然Http这种单向协议是不合适的,于是今天写一篇博客记录下WebSocket协议应用环境的搭建。
WebSocket概述
WebSocket是一种全双工模式协议,只需一次握手就能建立长连接,双向传输数据;如果我用的是Http协议,作为客户端我只能去找服务端,而服务端不能来找我;而WebSocket则可以让客户端和服务端相互联系。
Http:
客户端:你好,我快递到了吗?(Ajax请求)
服务端:没到。
客户端:你好,我快递到了吗?(再发Ajax请求)
服务端:没到...
客户端:你好,我快递到了吗?(还发Ajax请求)
服务端:没到啊啊啊啊
。。。。。。
WebSocket:
客户端:你好,我快递到了吗?
服务端:没到。
服务端:那我留个电话给你,到了你打我电话哈(建立联系)
服务端:好
快递到了,服务端打电话给客户端✔
大家看个乐,更严谨的还得看这里:WebSocket协议理解
服务端搭建
好,那我们开始websocket的应用吧,首先我们来搭建服务端;
创建一个SpringBoot项目
打开IDEA,选择File-> new-> project;选择Spring Initializr,如下图在Custom填入 https://start.aliyun.com/ :
随便填填,选择war打包
Maven导入jar包
打开pom文件,添加下列依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
创建WebSocket配置类
在 src\main\java\xx下 新建WebSocketConfig类:
@Component
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
创建WebSocket服务端类
新建WebSocket类:
@Component
@ServerEndpoint(value = "/webSocket")
public class WebSocket {
private Session session;
private String userId;
private static ConcurrentHashMap<String, WebSocket> webSocketMap = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session) {
this.session = session;
userId = session.getQueryString();
webSocketMap.put(userId, this);
System.out.println("新建连接,总数为" + webSocketSet.size());
}
@OnClose
public void onClose(Session session) {
webSocketMap.remove(userId);
System.out.println("断开连接,总数为" + webSocketSet.size());
}
@OnMessage
public void onMessage(String message, Session session) {
//这里写你的消息处理逻辑
sendMessage(JSONObject.parseObject(message,Message.class));
}
public void sendMessage(Message message) {
try {
webSocketMap.get(message.getTargetID())
.session.getBasicRemote()
.sendText(JSONObject.toJSONString(message));
} catch (IOException e) {
e.printStackTrace();
}
}
}
@ServerEndpoint(value = "/webSocket") 代表服务端的地址为:ws://localhost:8080/webSocket, 这里只给了服务端类的基本框架代码,你可以自行添加业务逻辑代码,我这里使用了自定义的Message类来包装消息;
客户端搭建
为了体现客户端与服务端分离,我们另外创建一个Maven项目 IMTest,选择简单的maven-quickstart框架即可,在这里搭建客户端。
添加Maven依赖
打开pom文件:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.1</version>
</dependency>
创建客户端类
我们创建一个MyWebSocketClient类继承WebSocketClient类,并重写里面的方法:
public class MyWebSocketClient extends WebSocketClient {
public MyWebSocketClient(URI serverUri) {
super(serverUri);
}
public MyWebSocketClient(URI serverUri, Draft protocolDraft) {
super(serverUri, protocolDraft);
}
@Override
public void onOpen(ServerHandshake serverHandshake) {
System.out.println("连接成功");
}
@Override
public void onMessage(String s) {
//在这里写你自己的消息处理方式
System.out.println("\n-------------------------");
Message message = JSONObject.parseObject(s,Message.class);
System.out.println(message.getDate() + "\n" + message.getSourceID() + ": " + message.getText());
System.out.println("-------------------------");
}
@Override
public void onMessage(ByteBuffer bytes) {
super.onMessage(bytes);
}
@Override
public void onClose(int i, String s, boolean b) {
System.out.println("连接关闭");
}
@Override
public void onError(Exception e) {
System.out.println("连接错误!");
}
}
测试
我们来测试一下能否正常的运行:
- 运行服务端
- 在IMTest项目创建两个类:ClientTest和ClientTest2:
public class ClientTest {
public static void main(String[] args) throws URISyntaxException, InterruptedException {
MyWebSocketClient myClient = new MyWebSocketClient(new URI("ws://localhost:8080/webSocket?123"));
myClient.connectBlocking();
Scanner in = new Scanner(System.in);
String str;
while (true) {
str = in.nextLine();
Message msg = new Message("123", "456", str);
myClient.send(JSONObject.toJSONString(msg));
}
}
}
//ClientTest2同理
- 运行ClientTest和ClientTest2,分别发送消息:
成功!
应用
到了这一步我们已经可以轻松的应用WebSocket来开发聊天、消息推送等功能了,同时这些在安卓也是可以同步的,比如:
下次发一个山寨微信APP,安卓客户端的,食堂 冲冲冲!
2021/11/10更: 做出来了,但已弃坑客户端!
Q.E.D.