(1) 个人总结:后台设置了websocket地址,服务器开启后等待有人去连接它。 一个客户端一打开就去连接websocket地址,同时传递某些识别参数。这样一来后台和客户端连接成功了,然后后台就可以发消息给客户端了,(客户端也可以再回话给后台)。
(2) socket叫套接字,应用程序用socket向网络发出请求或者应答网络请求。
(3) 官方解释的socket 建立连接四步骤:
服务器端开启socket,然后accep方法处于监听状态,等待客户端的连接。
客户端开启,指定服务器名称和端口号来请求连接服务器端的socket。
服务器端收到客户端连接请求,返回连接确认。在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。
客户端收到连接确认,两个人就连接好了,双方开始通讯
(4)注意:
客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。
TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送.
1、app.js写法
在app.js下添加三个函数openSocket(), closeSocket(),sendMessage(),在app初始化的onLunch函数里面调用openSocket(),这样子用户一进入小程序就会自动连接websocket
App({ globalData: { socketStatus: 'closed', }, onLaunch: function() { var that = this; if (that.globalData.socketStatus === 'closed') { that.openSocket(); } } openSocket() { //打开时的动作 wx.onSocketOpen(() => { console.log('WebSocket 已连接') this.globalData.socketStatus = 'connected'; this.sendMessage(); }) //断开时的动作 wx.onSocketClose(() => { console.log('WebSocket 已断开') this.globalData.socketStatus = 'closed' }) //报错时的动作 wx.onSocketError(error => { console.error('socket error:', error) }) // 监听服务器推送的消息 wx.onSocketMessage(message => { //把JSONStr转为JSON message = message.data.replace(" ", ""); if (typeof message != 'object') { message = message.replace(/\ufeff/g, ""); //重点 var jj = JSON.parse(message); message = jj; } console.log("【websocket监听到消息】内容如下:"); console.log(message); }) // 打开信道 wx.connectSocket({ url: "ws://" + "localhost" + ":8888", }) }, //关闭信道 closeSocket() { if (this.globalData.socketStatus === 'connected') { wx.closeSocket({ success: () => { this.globalData.socketStatus = 'closed' } }) } }, //发送消息函数 sendMessage() { if (this.globalData.socketStatus === 'connected') { //自定义的发给后台识别的参数 ,我这里发送的是name wx.sendSocketMessage({ data: "{\"name\":\"" + wx.getStorageSync('openid') + "\"}" }) } }, })
2、后台写法
主要有两个类,一个是websocket启动监听交互类,一个是存储当前所有已经连接好的用户池以及对这些用户的操作封装类
然后在项目启动类里面调用websocke启动监听交互类的启动方法。(如果是springboot项目,就直接在主类中调用)
(1)导入包
<dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>1.3.0</version> </dependency>
(2)启动websocket的方法,放在启动类里面
/** * 启动websocket */ public void startWebsocketInstantMsg() { WebSocketImpl.DEBUG = false; MyWebScoket s; s = new MyWebScoket(8888); s.start(); System.out.println("websocket启动成功"); }
(3)websocket监听交互类如下
该类涉及的监听方法有:监听用户连入;监听用户断开;监听消息发过来;监听有错误等
import com.alibaba.fastjson.JSONObject; import org.java_websocket.WebSocket; import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.server.WebSocketServer; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.Map; public class MyWebScoket extends WebSocketServer { public MyWebScoket() throws UnknownHostException { super(); } public MyWebScoket(int port) { super(new InetSocketAddress(port)); } public MyWebScoket(InetSocketAddress address) { super(address); } @Override public void onOpen(WebSocket conn, ClientHandshake handshake) { // ws连接的时候触发的代码,onOpen中我们不做任何操作 } @Override public void onClose(WebSocket conn, int code, String reason, boolean remote) { //断开连接时候触发代码 userLeave(conn); System.out.println(reason); } @Override public void onMessage(WebSocket conn, String message) { //有用户连接进来 Map<String, String> obj = (Map<String,String>) JSONObject.parse(message); System.out.println(message); String username = obj.get("name"); userJoin(conn, username); } @Override public void onError(WebSocket conn, Exception ex) { //错误时候触发的代码 System.out.println("on error"); ex.printStackTrace(); } /** * 去除掉失效的websocket链接 */ private void userLeave(WebSocket conn){ WsPool.removeUser(conn); } /** * 将websocket加入用户池 * @param conn * @param userName */ private void userJoin(WebSocket conn,String userName){ WsPool.addUser(userName, conn); } }
(4)用户池类如下