宝塔山 发表于 2022-10-27 05:43:54

WebSocket,IsWebSocketRequest与AspNetWebSocketContext

asp.net新建一个服务端程序,用来处理链接服务端:
1,新建一个处理程序 .ashx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.WebSockets;
using SFellowEntity.Models;

namespace SchoolfellowCard.Handler
{
    /// <summary>
    /// WebSocketServer webSocket服务
    /// </summary>
    public class WebSocketServer : IHttpHandler
    {
      //用户连接池
      private static Dictionary<string, WebSocket> connectPool = new Dictionary<string, WebSocket>();
      //离线消息池
      private static Dictionary<string, List<MessageInfo>> messagePool = new Dictionary<string, List<MessageInfo>>();

      public void ProcessRequest(HttpContext context)
      {
            if (context.IsWebSocketRequest)
            {
                context.AcceptWebSocketRequest(ProcessChat);
            }
      }
      /// <summary>
      /// webSocket异步作业
      /// </summary>
      /// <param name="context"></param>
      /// <returns></returns>
      private async Task ProcessChat(AspNetWebSocketContext context)
      {
            //WebSocket socket = context.WebSocket;
            //while (true)
            //{
            //    if (socket.State == WebSocketState.Open)
            //    {
            //      ArraySegment<byte> buffer = new ArraySegment<byte>(new byte);
            //      WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
            //      string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
            //      userMsg = "你发送了:" + userMsg + "于" + DateTime.Now.ToLongTimeString();
            //      buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
            //      await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
            //    }
            //    else
            //    {
            //      break;
            //    }
            //}
            WebSocket socket = context.WebSocket;
            string user =string.Format("{0}", context.QueryString["user"]);

            try
            {
                #region 验证用户添加连接池

                //第一次open时,添加到连接池中
                if (!connectPool.ContainsKey(user))
                {
                  connectPool.Add(user, socket); //不存在,添加
                }
                else
                {
                  if (socket != connectPool) //当前对象不一致,更新
                  {
                        connectPool = socket;
                  }
                }
               
                #endregion

                #region 离线消息处理
                if (messagePool.ContainsKey(user))
                {
                  //TODO:离线消息可放入数据库在此获取离线消息并返回给对应的用户
                  List<MessageInfo> msgs = messagePool;
                  foreach (MessageInfo item in msgs)
                  {
                        await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
                  }
                  messagePool.Remove(user);//移除离线消息
                  //TODO:处理完后标记离线消息已推送
                }
                #endregion

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

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

                            string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
                            string[] msgList = userMsg.Split('|');
                            if (msgList.Length == 2)
                            {
                              if (msgList.Trim().Length > 0)
                                    descUser = msgList.Trim();//记录消息目的用户//TODO:将消息接收者可放入数据库存贮记录
                              buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList));
                            }
                            else
                              buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));

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

      public bool IsReusable
      {
            get
            {
                return false;
            }
      }
    }

其中,MessageInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SFellowEntity.Models
{
    /// <summary>
    /// 消息
    /// </summary>
    public class MessageInfo
    {
      /// <summary>
      /// 消息内容
      /// </summary>
      public ArraySegment<byte> MsgContent { get; set; }
      /// <summary>
      /// 消息时间
      /// </summary>
      public DateTime MsgTime { get; set; }
      /// <summary>
      /// 构造函数
      /// </summary>
      /// <param name="msgTime"></param>
      /// <param name="msgContent"></param>
      public MessageInfo(DateTime msgTime, ArraySegment<byte> msgContent)
      {
            MsgTime = msgTime;
            MsgContent = msgContent;
      }
    }

 页面端:
2,页面JavaScript创建WebSocket对象,并发起连接
 
            $('#conn').click(function () {
                ws = new WebSocket('ws://' + window.location.hostname + ':' + window.location.port + '/Handler/WebSocketServer.ashx?user=' + $("#user").val());
                $('#msg').append('<p>正在连接</p>');

                ws.onopen = function () {
                  $('#msg').append('<p>已经连接</p>');
                }
                ws.onmessage = function (evt) {
                  $('#msg').append('<p>' + evt.data + '</p>');
                }
                ws.onerror = function (evt) {
                  $('#msg').append('<p>' + JSON.stringify(evt) + '</p>');
                }
                ws.onclose = function () {
                  $('#msg').append('<p>已经关闭</p>');
                }
            });

            $('#close').click(function () {
                ws.close();
            });

            $('#send').click(function () {
                if (ws.readyState == WebSocket.OPEN) {
                  ws.send($("#to").val() + "|" + $('#content').val());
                }
                else {
                  $('#tips').text('连接已经关闭');
                }
            }); 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: WebSocket,IsWebSocketRequest与AspNetWebSocketContext