博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springboot中的几种scope
阅读量:6470 次
发布时间:2019-06-23

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

回到顶部

写在开始

上面一篇写了一篇使用WebSocket做客户端,然后服务端是socke代码实现的。传送门:webSocket和Socket实现聊天群发

本来我是打算写到一章上的,毕竟实现的都是一样的功能,后来想了想就没写在一起,主要是两个方面,

一个原因是这是另一种实现服务方式,放在一起看着有点乱。单独写也方便查阅。二是写是分开写的回家晚上写一点,不能直接在原文上写,就重新起来一个草稿,但是写完就感觉有点懒,不想整合到一块了。嘿嘿,,,

所以对开头说的不明白的同学可以先看一下前面的东西。看一下基础,事半功倍哦。

这一篇不做功能的更改,既然我们使用了WebSocket为什么不使用到底哪,我不喜欢socket的里面出现的打包请求连接数据处理和发送数据处理。可以没有问题啊。那你继续往下看吧。

首先WebSocket服务器这篇我们还是实现的6个功能:

  • 单聊:可以指定人进行聊天。
  • 群发:这个的意思就是当前服务器内的所有人包含自己,这个就跟一个推送效果一样。
  • 开启连接(客户端):通知除自己以外的所有用户
  • 关闭连接(客户端):通知除自己以外的所有用户
  • 群组A:实现一个群组名字为A
  • 群组B:实现一个群组名字为B
回到顶部

技术点

前端写法都是一样的我就不做过多的叙述了,这里只要是针对socket协议的方法进行修改成WebSocket形式。

首先我这次是把服务写成了一般处理程序进行挂载的。(有些有强迫症的小伙伴想改访问路由路径可以参考一下:mvc中路由的映射和实现IHttpHandler挂载

我在本示例就是把放在model下的一个一般处理程序,改写成了socket路径.

原来访问是:http“//http://localhost:端口号/文件夹位置/SocketServer.ashx

改完之后是:http“//http://localhost:端口号/socket/SocketServer.ashx

在实际项目中可以不暴露文件的真是路径位置,还是有点用处的。

不得不说WebSocket确实不错,比如接受发送数据解析方法都给封装好了。

 

接受方式

既然使用WebSocket做协议当然接受就不用用socket而是使用WebSocket啦。通过在接受到请求后获取上下文中的WebSocket。

//创建新WebSocket实例            WebSocket myClientSocket = context.WebSocket;             string userId = context.QueryString["userId"];

在这里我们有一点变化就是socke用户是通过socket随机获取的,这里我修改成了页面传输。前台代码:

var userId = parseInt(Math.random() * (999999 - 100000 + 1) + 100000, 10);        console.log(userId)        ws = new WebSocket('ws://' + window.location.hostname + ':' + window.location.port + '/socket?userId=' + userId);

 

判读在线方式

WebSocket有单独的状态来进行在线的判断,不用我们自己写判断处理还是比较好的。

复制代码
#region 关闭Socket处理,删除连接池                            if (myClientSocket.State != WebSocketState.Open)//连接关闭                            {                                if (ListUser.ContainsKey(userId)) ListUser.Remove(userId);//删除连接池                                break;                            }                            #endregion
复制代码

 

接受数据

WebSocket也没有辜负我们的期望,接受数据的处理也不需要我们处理的,使用ReceiveAsync方法可以得到消息字节,我们只需要定义一个字节数组段用来接受即可,例如:

ArraySegment
buffer = new ArraySegment
(new byte[2048]);//定义字节数组 WebSocketReceiveResult result = await myClientSocket.ReceiveAsync(buffer, CancellationToken.None);//获得字节   string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息

是不是感觉特别的方便,没有了那些乱七八糟的处理了。看着还是挺舒心的。

 

发送数据

既然接受数据都有单独的方法封装,发送消息没有道理没有的,是的发送使用SendAsync方法,使用形式和ReceiveAsync类似,首先定义一个字节数组段用来存放内容,例如:

ArraySegment
buffer = new ArraySegment
(Encoding.UTF8.GetBytes($"用户({userIdA}=>{userIdB}):{msg}")); socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);

这样子就是一个发送过程,先把要发送的字符串转换成字节数组段,然后把这个数组段使用SendAsync发送出去就可以了。

 注:在上面的两个方法中我们都看到了ArraySegment这个东西,他到底是个什么哪,他是一个命名在System命名空间下的一个结构体。类似与Array数组但是他又不是数组,为什么这么说,因为他可以接受数组段,他可以只保存内容中的一部分而不是全部。就像别人说的小抽屉一样。我是把他理解成先把他放到这里当作数据缓存区,等真实发送的时候进行发送数据。WebSocketMessageType是一个枚举类型,通过F12可以看到:

复制代码
// 摘要:    //     指示消息类型:    public enum WebSocketMessageType    {        //        // 摘要:        //     该消息是明文形式。        Text = 0,        //        // 摘要:        //     消息采用二进制格式。        Binary = 1,        //        // 摘要:        //     因为收到关闭的消息,接受已完成。        Close = 2    }
复制代码
回到顶部

 敬上代码

 

入口函数

一般处理程序中判断只接受WebSocket协议连接进入的运行:

复制代码
if (context.IsWebSocketRequest)            {                context.AcceptWebSocketRequest(Accept);            }            else            {            }
复制代码

 

消息处理

下面就是同意连接后的主要方法,类似上一篇写的ReceiveMessage方法(接受消息),这里的处理存在一些改动,所以我就把所有代码贴上来了。

复制代码
1 #region 处理客户端连接请求 2         ///  3         /// 处理客户端连接请求 4         ///  5         ///  6         private async Task Accept(AspNetWebSocketContext context) 7         { 8             //创建新WebSocket实例 9             WebSocket myClientSocket = context.WebSocket;10             string userId = context.QueryString["userId"];11 12             try13             {14 15                 string descUser = string.Empty;//目的用户16                 while (true)17                 {18                     if (myClientSocket.State == WebSocketState.Open)19                     {20                         ArraySegment
buffer = new ArraySegment
(new byte[2048]);21 WebSocketReceiveResult result = await myClientSocket.ReceiveAsync(buffer, CancellationToken.None);22 23 #region 消息处理(字符截取、消息转发)24 try25 {26 #region 关闭Socket处理,删除连接池27 if (myClientSocket.State != WebSocketState.Open)//连接关闭28 {29 30 if (ListUser.ContainsKey(userId))31 {32 //退出 33 SignOut(userId);34 ListUser.Remove(userId);//删除连接池35 Debug.WriteLine("当前退出用户:" + userId);36 }37 break;38 }39 #endregion40 string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息41 string[] resultList = userMsg.Split(',');42 if (resultList[0] == "login")43 {44 //登录45 Login(userId);46 #region 用户添加连接池47 //第一次open时,添加到连接池中48 if (!ListUser.ContainsKey(userId))49 ListUser.Add(userId, myClientSocket);//不存在,添加50 else51 if (myClientSocket != ListUser[userId])//当前对象不一致,更新52 ListUser[userId] = myClientSocket;53 #endregion54 Debug.WriteLine("当前登录用户:" + userId);55 }56 else if (resultList[0] == "all")57 {58 //群发所有用户59 GroupChat(userId, resultList[1]);60 }61 else if (resultList[0] == "groupA")62 {63 //群组发送64 GroupChatA("groupA", userId, resultList[1]);65 }66 else if (resultList[0] == "groupB")67 {68 //群组发送69 GroupChatA("groupB", userId, resultList[1]);70 }71 else72 {73 //单聊74 SingleChat(userId, resultList[0], resultList[1]);75 }76 77 }78 catch (Exception exs)79 {80 //消息转发异常处理,本次消息忽略 继续监听接下来的消息81 }82 #endregion83 }84 else85 {86 break;87 }88 }//while end89 }90 catch (Exception ex)91 {92 Console.WriteLine("Error : " + ex.ToString());93 }94 }95 #endregion
复制代码

 

 单聊实现

这里我就不把写的所有单聊,群里,实现群组方法贴上来了,实现的思路还是和以前一样,只是写法不同,我就写一个单聊作为代表示例贴上来。想看全部在下面下载源码就好了。

复制代码
#region 单聊        public void SingleChat(string userIdA, string userIdB, string msg)        {            WebSocket socket = ListUser[userIdB];            if (socket != null)            {                if (socket !www.leyou2.net = null && socket.State == WebSocketState.Open)                {                    ArraySegment
www.feifanyule.cn buffer =www.yongshiyule178.com new ArraySegment
(Encoding.UTF8.GetBytes($"用户({userIdA}=>{userIdB}):{msg}")); socket.SendAsync(buffer, WebSocketMessageType.Binary, true, CancellationToken.None); } } } #endregion
复制代码
回到顶部

 传送门:

基础版本实现简单的websocket:实现服务端webSocket连接通讯

完善websocket实现聊天示例:WebSocket和Socket实现聊天群发

转载地址:http://xtcko.baihongyu.com/

你可能感兴趣的文章
幸福框架:可扩展的、动态的、万能的 编号生成器
查看>>
黄聪:PHP 防护XSS,SQL,代码执行,文件包含等多种高危漏洞
查看>>
svn status 显示 ~xx
查看>>
常用HiveQL总结
查看>>
[转]使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(三)-- Logger
查看>>
POJ 3311 Hie with the Pie(状压DP + Floyd)
查看>>
HDU 1402 A * B Problem Plus FFT
查看>>
Security updates and resources
查看>>
深入理解JavaScript系列(25):设计模式之单例模式
查看>>
DNS为什么通常都会设置为14.114.114.114
查看>>
给定一个序列,判断该序列是否为二叉树查找树的后序遍历序列
查看>>
Sqoop架构(四)
查看>>
golang copy函数
查看>>
《你有多少问题要请示》精华集粹
查看>>
深度 | 机器学习敲门砖:任何人都能看懂的TensorFlow介绍【转】
查看>>
leveldb学习:DBimpl
查看>>
[Recompose] Stream Props to React Children with RxJS
查看>>
打印图片
查看>>
SHOW CREATE DATABASE Syntax
查看>>
rsync常见问题及解决办法
查看>>