微信小程序使用websocket通讯的demo,含前后端代码,亲测可用
0、概述websocket
(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(){
varthat=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('socketerror:',error)
})
//监听服务器推送的消息
wx.onSocketMessage(message=>{
//把JSONStr转为JSON
message=message.data.replace("","");
if(typeofmessage!='object'){
message=message.replace(/\ufeff/g,"");//重点
varjj=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)导入包
org.java-websocket Java-WebSocket 1.3.0
(2)启动websocket的方法,放在启动类里面
/**
*启动websocket
*/
publicvoidstartWebsocketInstantMsg(){
WebSocketImpl.DEBUG=false;
MyWebScokets;
s=newMyWebScoket(8888);
s.start();
System.out.println("websocket启动成功");
}
(3)websocket监听交互类如下
该类涉及的监听方法有:监听用户连入;监听用户断开;监听消息发过来;监听有错误等
importcom.alibaba.fastjson.JSONObject;
importorg.java_websocket.WebSocket;
importorg.java_websocket.handshake.ClientHandshake;
importorg.java_websocket.server.WebSocketServer;
importjava.net.InetSocketAddress;
importjava.net.UnknownHostException;
importjava.util.Map;
publicclassMyWebScoketextendsWebSocketServer{
publicMyWebScoket()throwsUnknownHostException{
super();
}
publicMyWebScoket(intport){
super(newInetSocketAddress(port));
}
publicMyWebScoket(InetSocketAddressaddress){
super(address);
}
@Override
publicvoidonOpen(WebSocketconn,ClientHandshakehandshake){
//ws连接的时候触发的代码,onOpen中我们不做任何操作
}
@Override
publicvoidonClose(WebSocketconn,intcode,Stringreason,booleanremote){
//断开连接时候触发代码
userLeave(conn);
System.out.println(reason);
}
@Override
publicvoidonMessage(WebSocketconn,Stringmessage){
//有用户连接进来
Mapobj=(Map)JSONObject.parse(message);
System.out.println(message);
Stringusername=obj.get("name");
userJoin(conn,username);
}
@Override
publicvoidonError(WebSocketconn,Exceptionex){
//错误时候触发的代码
System.out.println("onerror");
ex.printStackTrace();
}
/**
*去除掉失效的websocket链接
*/
privatevoiduserLeave(WebSocketconn){
WsPool.removeUser(conn);
}
/**
*将websocket加入用户池
*@paramconn
*@paramuserName
*/
privatevoiduserJoin(WebSocketconn,StringuserName){
WsPool.addUser(userName,conn);
}
}
(4)用户池类如下
该类包含的方法有:从池中移除或添加用户;获取当前在线的所有用户;通过参数"name"获取某个用户的当前WebSocket连接;给某个WebSocket连接发送消息;为所有WebSocket连接发送消息等等
importcom.td.yousan.util.StringUtils;
importorg.java_websocket.WebSocket;
importjava.util.*;
publicclassWsPool{
privatestaticfinalMapwsUserMap=newHashMap();
/**
*通过websocket连接获取其对应的用户
*/
publicstaticStringgetUserByWs(WebSocketconn){
returnwsUserMap.get(conn);
}
/**
*根据userName获取WebSocket,这是一个list,此处取第一个
*因为有可能多个websocket对应一个userName(但一般是只有一个,因为在close方法中,我们将失效的websocket连接去除了)
*/
publicstaticWebSocketgetWsByUser(StringuserName){
SetkeySet=wsUserMap.keySet();
synchronized(keySet){
for(WebSocketconn:keySet){
Stringcuser=wsUserMap.get(conn);
if(cuser.equals(userName)){
returnconn;
}
}
}
returnnull;
}
/**
*向连接池中添加连接
*/
publicstaticvoidaddUser(StringuserName,WebSocketconn){
wsUserMap.put(conn,userName);//添加连接
}
/**
*获取所有连接池中的用户,因为set是不允许重复的,所以可以得到无重复的user数组
*/
publicstaticCollectiongetOnlineUser(){
ListsetUsers=newArrayList();
CollectionsetUser=wsUserMap.values();
for(Stringu:setUser){
setUsers.add(u);
}
returnsetUsers;
}
/**
*移除连接池中的连接
*/
publicstaticbooleanremoveUser(WebSocketconn){
if(wsUserMap.containsKey(conn)){
wsUserMap.remove(conn);//移除连接
returntrue;
}else{
returnfalse;
}
}
/**
*向特定的用户发送数据
*/
publicstaticvoidsendMessageToUser(WebSocketconn,Stringmessage){
if(null!=conn&&null!=wsUserMap.get(conn)){
conn.send(message);
}
}
/**
*向所有用户名中包含某个特征得用户发送消息
*/
publicstaticvoidsendMessageToSpecialUser(Stringmessage,Stringspecial){
SetkeySet=wsUserMap.keySet();
if(special==null){
special="";
}
synchronized(keySet){
for(WebSocketconn:keySet){
Stringuser=wsUserMap.get(conn);
try{
if(user!=null){
String[]cus=user.split("_");
if(!StringUtils.isNullOrEmpty(cus[0])){
StringcusDot=","+cus[0]+",";
if(cusDot.contains(","+special+",")){
conn.send(message);
}
}else{
conn.send(message);
}
}
}catch(Exceptione){
e.printStackTrace();
//wsUserMap.remove(conn);
}
}
}
}
/**
*向所有的用户发送消息
*/
publicstaticvoidsendMessageToAll(Stringmessage){
SetkeySet=wsUserMap.keySet();
synchronized(keySet){
for(WebSocketconn:keySet){
Stringuser=wsUserMap.get(conn);
if(user!=null){
conn.send(message);
}
}
}
}
}
总结
以上所述是小编给大家介绍的微信小程序使用websocket通讯的demo,含前后端代码,亲测可用,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!