小程序之WebSocket

一,首先大家要先了解一下什么是WebSocket
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

原先的http协议,无法实现服务器主动向客户端发起消息,如果想动态获取服务器数据,浏览器需要不断的向服务器发出请求,那么只有轮询,然而这样,极易消耗服务器资源,
打一个比喻,就好比打电话,
http:
客户端:喂,大哥啊,有没有新的数据啊
服务器:没有,…
客户端:哦,那我挂了,滴滴滴…

客户端:喂大哥,这次有没有新的数据啊,
服务器:没有…
客户端:哦,那我挂了。。。滴滴滴…
服务器:哎哎,别急,有了有了,额,,,麻蛋敢挂我电话,劳资不管了

websocket:
客户端:喂,大哥,有数据了,给我打个招呼啊,下班了,请你吃麻辣烫
服务器:好的,兄弟,没问题

是不是顿时明白了好多
当你创建一个websocket时,就等于创建一个信息交互通道,这个通道一直保持着数据实时通信,废话不多说,你可以参考一下文档参考文档

下面是我做小程序时,针对ws的应用

 wx.connectSocket({//创建一个ws链接
      url: 'ws://'
    })
    wx.onSocketError(function(res) {//监听连接错误信息
      console.log(res)
    })
    wx.onSocketOpen(function() {//监听连接打开信息
      console.log("已经打开")
    })
    var that = this;
    wx.onSocketMessage(function(res) {//获取服务器发来的消息

      console.log("收到消息" + res.data)
      var percents;
      percents = that.data.percent + parseInt(res.data)
      if (that.data.percent >= 100) {
        percents = 1
      }
      that.setData({//动态渲染数据
        percent: percents,
      })
    })

下面是我服务器针对websocket请求处理

 public class MessageInfo
    {
        public MessageInfo(DateTime _MsgTime, ArraySegment<byte> _MsgContent)
        {
            MsgTime = _MsgTime;
            MsgContent = _MsgContent;
        }
        public DateTime MsgTime { get; set; }
        public ArraySegment<byte> MsgContent { get; set; }
    }

    /// <summary>
    /// Handler1 的摘要说明
    /// </summary>
    public class Handler : IHttpHandler
    {
        private static Dictionary<string, WebSocket> CONNECT_POOL = new Dictionary<string, WebSocket>();//用户连接池
        private static Dictionary<string, List<MessageInfo>> MESSAGE_POOL = new Dictionary<string, List<MessageInfo>>();//离线消息池
        public void ProcessRequest(HttpContext context)
        {
           string type= context.Request.QueryString["type"];
            if (context.IsWebSocketRequest)
            {
                try
                {
                    context.AcceptWebSocketRequest(ProcessChat);
                }
                catch (Exception e)
                {
                    return;
                }
            }
            if (type=="getfac")
            {
                string openid= context.Request.QueryString["openid"];
                GetJsonRequest(context, openid);
            }
        }
        /// <summary>
        /// WebSocket请求操作
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private async Task ProcessChat(AspNetWebSocketContext context)
        {
            WebSocket socket = context.WebSocket;
            string user = context.QueryString["user"].ToString();

            try
            {
                #region 用户添加连接池
                //第一次open时,添加到连接池中
                if (!CONNECT_POOL.ContainsKey(user))
                    CONNECT_POOL.Add(user, socket);//不存在,添加
                else
                    if (socket != CONNECT_POOL[user])//当前对象不一致,更新
                    CONNECT_POOL[user] = socket;
                #endregion
                #region 离线消息处理
                if (MESSAGE_POOL.ContainsKey(user))
                {
                    List<MessageInfo> msgs = MESSAGE_POOL[user];
                    foreach (MessageInfo item in msgs)
                    {
                        await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
                    }
                    MESSAGE_POOL.Remove(user);//移除离线消息
                }
                #endregion

                string descUser = string.Empty;//目的用户
                while (true)
                {
                    if (socket.State == WebSocketState.Open)
                    {
                        ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
                        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);

                        #region 消息处理(字符截取、消息转发)
                        try
                        {
                            #region 关闭Socket处理,删除连接池
                            if (socket.State != WebSocketState.Open)//连接关闭
                            {
                                if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);//删除连接池
                                break;
                            }
                            #endregion

                            string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
                            string[] msgList = userMsg.Split('|');
                            if (msgList.Length == 2)
                            {
                                if (msgList[0].Trim().Length > 0)
                                    descUser = msgList[0].Trim();//记录消息目的用户
                                buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
                            }
                            else
                                buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));

                            if (CONNECT_POOL.ContainsKey(descUser))//判断客户端是否在线
                            {
                                WebSocket destSocket = CONNECT_POOL[descUser];//目的客户端
                                if (destSocket != null && destSocket.State == WebSocketState.Open)
                                    await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                            }
                            else
                            {
                                Task.Run(() =>
                                {
                                    if (!MESSAGE_POOL.ContainsKey(descUser))//将用户添加至离线消息池中
                                        MESSAGE_POOL.Add(descUser, new List<MessageInfo>());
                                    MESSAGE_POOL[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
                                });
                            }
                        }
                        catch (Exception exs)
                        {
                            //消息转发异常处理,本次消息忽略 继续监听接下来的消息
                        }
                        #endregion
                    }
                    else
                    {
                        break;
                    }
                }//while end
            }
            catch (Exception ex)
            {
                //整体异常处理
                if (CONNECT_POOL.ContainsKey(user)) CONNECT_POOL.Remove(user);
            }
        }
        }

原来每个客户端只能创建一个websocket,现在小程序可以创建两个,官方不断更新,我相信,以后可能不止两个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值