博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
微信小程序使用websocket通讯的demo,含前后端代码,亲测可用
阅读量:5334 次
发布时间:2019-06-15

本文共 7127 字,大约阅读时间需要 23 分钟。

目录

1502888-20190522145853381-1697794616.png

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() {           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)导入包

org.java-websocket
Java-WebSocket
1.3.0

(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
obj = (Map
) 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)用户池类如下

该类包含的方法有:从池中移除或添加用户;获取当前在线的所有用户;通过参数"name"获取某个用户的当前WebSocket连接;给某个WebSocket连接发送消息;为所有WebSocket连接发送消息等等

import com.td.yousan.util.StringUtils;import org.java_websocket.WebSocket;import java.util.*;public class WsPool {    private static final Map
wsUserMap = new HashMap
(); /** * 通过websocket连接获取其对应的用户 */ public static String getUserByWs(WebSocket conn) { return wsUserMap.get(conn); } /** * 根据userName获取WebSocket,这是一个list,此处取第一个 * 因为有可能多个websocket对应一个userName(但一般是只有一个,因为在close方法中,我们将失效的websocket连接去除了) */ public static WebSocket getWsByUser(String userName) { Set
keySet = wsUserMap.keySet(); synchronized (keySet) { for (WebSocket conn : keySet) { String cuser = wsUserMap.get(conn); if (cuser.equals(userName)) { return conn; } } } return null; } /** * 向连接池中添加连接 */ public static void addUser(String userName, WebSocket conn) { wsUserMap.put(conn, userName); // 添加连接 } /** * 获取所有连接池中的用户,因为set是不允许重复的,所以可以得到无重复的user数组 */ public static Collection
getOnlineUser() { List
setUsers = new ArrayList
(); Collection
setUser = wsUserMap.values(); for (String u : setUser) { setUsers.add(u); } return setUsers; } /** * 移除连接池中的连接 */ public static boolean removeUser(WebSocket conn) { if (wsUserMap.containsKey(conn)) { wsUserMap.remove(conn); // 移除连接 return true; } else { return false; } } /** * 向特定的用户发送数据 */ public static void sendMessageToUser(WebSocket conn, String message) { if (null != conn && null != wsUserMap.get(conn)) { conn.send(message); } } /** * 向所有用户名中包含某个特征得用户发送消息 */ public static void sendMessageToSpecialUser(String message,String special) { Set
keySet = wsUserMap.keySet(); if (special == null) { special = ""; } synchronized (keySet) { for (WebSocket conn:keySet) { String user = wsUserMap.get(conn); try { if (user != null) { String [] cus = user.split("_"); if (!StringUtils.isNullOrEmpty(cus[0])) { String cusDot = "," + cus[0] + ","; if (cusDot.contains(","+special+",")) { conn.send(message); } }else { conn.send(message); } } }catch (Exception e) { e.printStackTrace(); //wsUserMap.remove(conn); } } } } /** * 向所有的用户发送消息 */ public static void sendMessageToAll(String message) { Set
keySet = wsUserMap.keySet(); synchronized (keySet) { for (WebSocket conn : keySet) { String user = wsUserMap.get(conn); if (user != null) { conn.send(message); } } } } }

转载于:https://www.cnblogs.com/ranandrun/p/miniWebsocket.html

你可能感兴趣的文章
LeetCode235——Lowest Common Ancestor of a Binary Search Tree
查看>>
android Title滑块动画实现(适合新闻client多种栏目的展示)
查看>>
ubuntu16下面 redis 无法链接到客户端问题
查看>>
android下实现4分屏播放4路高清h264格式的rtsp流
查看>>
[计算机网络] vsftpd的安装与使用
查看>>
【源代码】LinkedList源代码分析
查看>>
Cocostudio学习笔记(4) LoadingBar+ TextField
查看>>
cxf和jboss eap 6.2版本号冲突
查看>>
ORACLE触发器具体解释
查看>>
IOS开发之SVN的使用
查看>>
Python学习之元组
查看>>
第三次作业
查看>>
quartz多任务调度+spring 实现
查看>>
Codeforces 97.B Superset
查看>>
noip2008 笨小猴
查看>>
洛谷P1459 三值的排序 Sorting a Three-Valued Sequence
查看>>
合并流
查看>>
Nosql数据库教程之初探MongoDB
查看>>
Orchard详解--第三篇 依赖注入之基础设施
查看>>
ASP.NET没有魔法——ASP.NET MVC路由
查看>>