ToB企服应用市场:ToB评测及商务社交产业平台

标题: WebSocket,IsWebSocketRequest与AspNetWebSocketContext [打印本页]

作者: 宝塔山    时间: 2022-10-27 05:43
标题: WebSocket,IsWebSocketRequest与AspNetWebSocketContext
asp.net新建一个服务端程序,用来处理链接服务端:
1,新建一个处理程序 .ashx
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.WebSockets;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using System.Web;
  9. using System.Web.WebSockets;
  10. using SFellowEntity.Models;
  11. namespace SchoolfellowCard.Handler
  12. {
  13.     /// <summary>
  14.     /// WebSocketServer webSocket服务
  15.     /// </summary>
  16.     public class WebSocketServer : IHttpHandler
  17.     {
  18.         //用户连接池
  19.         private static Dictionary<string, WebSocket> connectPool = new Dictionary<string, WebSocket>();
  20.         //离线消息池
  21.         private static Dictionary<string, List<MessageInfo>> messagePool = new Dictionary<string, List<MessageInfo>>();
  22.         public void ProcessRequest(HttpContext context)
  23.         {
  24.             if (context.IsWebSocketRequest)
  25.             {
  26.                 context.AcceptWebSocketRequest(ProcessChat);
  27.             }
  28.         }
  29.         /// <summary>
  30.         /// webSocket异步作业
  31.         /// </summary>
  32.         /// <param name="context"></param>
  33.         /// <returns></returns>
  34.         private async Task ProcessChat(AspNetWebSocketContext context)
  35.         {
  36.             //WebSocket socket = context.WebSocket;
  37.             //while (true)
  38.             //{
  39.             //    if (socket.State == WebSocketState.Open)
  40.             //    {
  41.             //        ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
  42.             //        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
  43.             //        string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
  44.             //        userMsg = "你发送了:" + userMsg + "于" + DateTime.Now.ToLongTimeString();
  45.             //        buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
  46.             //        await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
  47.             //    }
  48.             //    else
  49.             //    {
  50.             //        break;
  51.             //    }
  52.             //}
  53.             WebSocket socket = context.WebSocket;
  54.             string user =string.Format("{0}", context.QueryString["user"]);
  55.             try
  56.             {
  57.                 #region 验证用户添加连接池
  58.                 //第一次open时,添加到连接池中
  59.                 if (!connectPool.ContainsKey(user))
  60.                 {
  61.                     connectPool.Add(user, socket); //不存在,添加
  62.                 }
  63.                 else
  64.                 {
  65.                     if (socket != connectPool[user]) //当前对象不一致,更新
  66.                     {
  67.                         connectPool[user] = socket;
  68.                     }
  69.                 }
  70.                
  71.                 #endregion
  72.                 #region 离线消息处理
  73.                 if (messagePool.ContainsKey(user))
  74.                 {
  75.                     //TODO:离线消息可放入数据库在此获取离线消息并返回给对应的用户
  76.                     List<MessageInfo> msgs = messagePool[user];
  77.                     foreach (MessageInfo item in msgs)
  78.                     {
  79.                         await socket.SendAsync(item.MsgContent, WebSocketMessageType.Text, true, CancellationToken.None);
  80.                     }
  81.                     messagePool.Remove(user);//移除离线消息
  82.                     //TODO:处理完后标记离线消息已推送
  83.                 }
  84.                 #endregion
  85.                 string descUser = string.Empty;//目的用户
  86.                 while (true)
  87.                 {
  88.                     if (socket.State == WebSocketState.Open)
  89.                     {
  90.                         ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
  91.                         //websocket接收消息
  92.                         WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
  93.                         #region 消息处理(字符截取、消息转发)
  94.                         try
  95.                         {
  96.                             #region 关闭Socket处理,删除连接池
  97.                             if (socket.State != WebSocketState.Open)//连接关闭
  98.                             {
  99.                                 if (connectPool.ContainsKey(user)) connectPool.Remove(user);//删除连接池
  100.                                 break;
  101.                             }
  102.                             #endregion
  103.                             string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息
  104.                             string[] msgList = userMsg.Split('|');
  105.                             if (msgList.Length == 2)
  106.                             {
  107.                                 if (msgList[0].Trim().Length > 0)
  108.                                     descUser = msgList[0].Trim();//记录消息目的用户//TODO:将消息接收者可放入数据库存贮记录
  109.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgList[1]));
  110.                             }
  111.                             else
  112.                                 buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMsg));
  113.                             if (connectPool.ContainsKey(descUser))//判断客户端是否在线
  114.                             {
  115.                                 WebSocket destSocket = connectPool[descUser];//目的客户端
  116.                                 if (destSocket != null && destSocket.State == WebSocketState.Open)
  117.                                     await destSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
  118.                             }
  119.                             else
  120.                             {
  121.                                 Task.Run(() =>
  122.                                 {
  123.                                     if (!messagePool.ContainsKey(descUser))//将用户添加至离线消息池中
  124.                                         messagePool.Add(descUser, new List<MessageInfo>());
  125.                                     messagePool[descUser].Add(new MessageInfo(DateTime.Now, buffer));//添加离线消息
  126.                                     //TODO:离线消息插入数据库
  127.                                 });
  128.                             }
  129.                         }
  130.                         catch (Exception exs)
  131.                         {
  132.                             //消息转发异常处理,本次消息忽略 继续监听接下来的消息
  133.                         }
  134.                         #endregion
  135.                     }
  136.                     else
  137.                     {
  138.                         break;
  139.                     }
  140.                 }//while end
  141.             }
  142.             catch (Exception ex)
  143.             {
  144.                 //整体异常处理
  145.                 if (connectPool.ContainsKey(user)) connectPool.Remove(user);
  146.             }
  147.         }
  148.         public bool IsReusable
  149.         {
  150.             get
  151.             {
  152.                 return false;
  153.             }
  154.         }
  155.     }
  156. }
复制代码
 
其中,MessageInfo.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace SFellowEntity.Models
  7. {
  8.     /// <summary>
  9.     /// 消息
  10.     /// </summary>
  11.     public class MessageInfo
  12.     {
  13.         /// <summary>
  14.         /// 消息内容
  15.         /// </summary>
  16.         public ArraySegment<byte> MsgContent { get; set; }
  17.         /// <summary>
  18.         /// 消息时间
  19.         /// </summary>
  20.         public DateTime MsgTime { get; set; }
  21.         /// <summary>
  22.         /// 构造函数
  23.         /// </summary>
  24.         /// <param name="msgTime"></param>
  25.         /// <param name="msgContent"></param>
  26.         public MessageInfo(DateTime msgTime, ArraySegment<byte> msgContent)
  27.         {
  28.             MsgTime = msgTime;
  29.             MsgContent = msgContent;
  30.         }
  31.     }
  32. }
复制代码
 
 页面端:
2,页面JavaScript创建WebSocket对象,并发起连接
 
  1.             $('#conn').click(function () {
  2.                 ws = new WebSocket('ws://' + window.location.hostname + ':' + window.location.port + '/Handler/WebSocketServer.ashx?user=' + $("#user").val());
  3.                 $('#msg').append('<p>正在连接</p>');
  4.                 ws.onopen = function () {
  5.                     $('#msg').append('<p>已经连接</p>');
  6.                 }
  7.                 ws.onmessage = function (evt) {
  8.                     $('#msg').append('<p>' + evt.data + '</p>');
  9.                 }
  10.                 ws.onerror = function (evt) {
  11.                     $('#msg').append('<p>' + JSON.stringify(evt) + '</p>');
  12.                 }
  13.                 ws.onclose = function () {
  14.                     $('#msg').append('<p>已经关闭</p>');
  15.                 }
  16.             });
  17.             $('#close').click(function () {
  18.                 ws.close();
  19.             });
  20.             $('#send').click(function () {
  21.                 if (ws.readyState == WebSocket.OPEN) {
  22.                     ws.send($("#to").val() + "|" + $('#content').val());
  23.                 }
  24.                 else {
  25.                     $('#tips').text('连接已经关闭');
  26.                 }
  27.             });
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4