写在开始

上面一篇写了一篇使用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<byte> buffer = new ArraySegment<byte>(new byte[]);//定义字节数组
WebSocketReceiveResult result = await myClientSocket.ReceiveAsync(buffer, CancellationToken.None);//获得字节
  string userMsg = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);//发送过来的消息

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

发送数据

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

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

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

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

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

敬上代码

入口函数

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

            if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(Accept);
}
else
{ }

消息处理

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

 #region 处理客户端连接请求
/// <summary>
/// 处理客户端连接请求
/// </summary>
/// <param name="result"></param>
private async Task Accept(AspNetWebSocketContext context)
{
//创建新WebSocket实例
WebSocket myClientSocket = context.WebSocket;
string userId = context.QueryString["userId"]; try
{ string descUser = string.Empty;//目的用户
while (true)
{
if (myClientSocket.State == WebSocketState.Open)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[]);
WebSocketReceiveResult result = await myClientSocket.ReceiveAsync(buffer, CancellationToken.None); #region 消息处理(字符截取、消息转发)
try
{
#region 关闭Socket处理,删除连接池
if (myClientSocket.State != WebSocketState.Open)//连接关闭
{ if (ListUser.ContainsKey(userId))
{
//退出
SignOut(userId);
ListUser.Remove(userId);//删除连接池
Debug.WriteLine("当前退出用户:" + userId);
}
break;
}
#endregion
string userMsg = Encoding.UTF8.GetString(buffer.Array, , result.Count);//发送过来的消息
string[] resultList = userMsg.Split(',');
if (resultList[] == "login")
{
//登录
Login(userId);
#region 用户添加连接池
//第一次open时,添加到连接池中
if (!ListUser.ContainsKey(userId))
ListUser.Add(userId, myClientSocket);//不存在,添加
else
if (myClientSocket != ListUser[userId])//当前对象不一致,更新
ListUser[userId] = myClientSocket;
#endregion
Debug.WriteLine("当前登录用户:" + userId);
}
else if (resultList[] == "all")
{
//群发所有用户
GroupChat(userId, resultList[]);
}
else if (resultList[] == "groupA")
{
//群组发送
GroupChatA("groupA", userId, resultList[]);
}
else if (resultList[] == "groupB")
{
//群组发送
GroupChatA("groupB", userId, resultList[]);
}
else
{
//单聊
SingleChat(userId, resultList[], resultList[]);
} }
catch (Exception exs)
{
//消息转发异常处理,本次消息忽略 继续监听接下来的消息
}
#endregion
}
else
{
break;
}
}//while end
}
catch (Exception ex)
{
Console.WriteLine("Error : " + ex.ToString());
}
}
#endregion

单聊实现

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

 #region 单聊
public void SingleChat(string userIdA, string userIdB, string msg)
{
WebSocket socket = ListUser[userIdB];
if (socket != null)
{
if (socket != null && socket.State == WebSocketState.Open)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes($"用户({userIdA}=>{userIdB}):{msg}"));
socket.SendAsync(buffer, WebSocketMessageType.Binary, true, CancellationToken.None);
}
} }
#endregion

传送门:

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

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

最后在送上github源码:https://github.com/Yanbigfeng/WebSocketToSocket

【WebSocket No.3】使用WebSocket协议来做服务器的更多相关文章

  1. 开源的C#实现WebSocket协议客户端和服务器websocket-sharp组件解析

    很久没有写博客了(至少自己感觉很长时间没有写了),没办法啊,楼主也是需要生活的人啊,这段一直都在找工作什么的.(整天催我代码的人,还望多多谅解啊,我会坚持写我们的项目的,还是需要相信我的,毕竟这是一个 ...

  2. C#实现WebSocket协议客户端和服务器websocket sharp组件实例解析

    看到这篇文章的题目,估计很多人都会问,这个组件是不是有些显的无聊了,说到web通信,很多人都会想到ASP.NET SignalR,或者Nodejs等等,实现web的网络实时通讯.有关于web实时通信的 ...

  3. websocket --- 05 . http与websocket

    一.http协议 1.基于 TCP 协议 2.一次请求 一次响应 断开 3.客户端永远处于主动状态 4.服务器永远处于被动状态 5.Http无状态 - 在服务器不保存客户端的信息 6.服务器无法主动找 ...

  4. WebSocket实践——Java实现WebSocket的两种方式

    什么是 WebSocket? 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信 ...

  5. WebSocket 实战之——【WebSocket 原理】

    一.WebSocket是什么? HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算). 首先HTTP有1.1和1.0之说,也就 ...

  6. Spring WebSocket初探2 (Spring WebSocket入门教程)<转>

    See more: Spring WebSocket reference整个例子属于WiseMenuFrameWork的一部分,可以将整个项目Clone下来,如果朋友们有需求,我可以整理一个独立的de ...

  7. WebSocket(二)-WebSocket、Socket、TCP、HTTP区别

    原文地址:Socket 与 WebSocket 1. 概述 WebSocket 是为了满足基于 Web 的日益增长的实时通信需求而产生的.在传统的 Web 中,要实现实时通信,通用的方式是采用 HTT ...

  8. websocket之二:WebSocket编程入门

    一.WebSocket客户端 websocket允许通过JavaScript建立与远程服务器的连接,从而实现客户端与服务器间双向的通信.在websocket中有两个方法: 1.send() 向远程服务 ...

  9. 从日常开发说起,浅谈HTTP协议是做什么的。

    引言 HTTP协议作为Web开发的基础一直被大多数人所熟知,不过相信有很多人只知其一不知其二.比如咱们经常用到的session会话机制是如何实现的,可能很多人都说不出来吧.其实session会话就是H ...

随机推荐

  1. bash基础特性3(shell编程)

    Linux上文本处理三剑客: grep:文本过滤工具 sed:stream editor,文本编辑工具 awk:文本报告生成器 grep -v:显示不能够被pattern匹配到的行 -i:忽略字符大小 ...

  2. 背水一战 Windows 10 (106) - 通知(Toast): 通过 toast 打开协议, 通过 toast 选择在指定的时间之后延迟提醒或者取消延迟提醒

    [源码下载] 背水一战 Windows 10 (106) - 通知(Toast): 通过 toast 打开协议, 通过 toast 选择在指定的时间之后延迟提醒或者取消延迟提醒 作者:webabcd ...

  3. 如何优化Spring Cloud微服务注册中心架构?

    作者: 石杉的架构笔记 1.再回顾:什么是服务注册中心? 先回顾一下什么叫做服务注册中心? 顾名思义,假设你有一个分布式系统,里面包含了多个服务,部署在不同的机器上,然后这些不同机器上的服务之间要互相 ...

  4. 打开Python IDLE时的错误:Subprocess Startup Error

    比较常见的是这个 方法1: 修改[Python目录]\Lib\idlelib\PyShell.py文件,在1300行附近,将def main():函数下面 use_subprocess = True ...

  5. 每天学点SpringCloud(十四):Zipkin使用SpringCloud Stream以及Elasticsearch

    在前面的文章中,我们已经成功的使用Zipkin收集了项目的调用链日志.但是呢,由于我们收集链路信息时采用的是http请求方式收集的,而且链路信息没有进行保存,ZipkinServer一旦重启后就会所有 ...

  6. system libzip must be upgraded to version >= 0.11

    PHP当前最新版本是PHP7.3,今天在尝试安装的过程中报如下错误: system libzip must be upgraded to version >= 0.11, 根据提示我们可以清楚的 ...

  7. PHP全栈学习笔记18

    php基础知识,JavaScript,jQuery,ajax基础知识 linux基础知识,mysql数据库的基础与优化 程序设计,PHP框架基础知识,算法,逻辑思维,高并发 PHP基础知识 引用变量, ...

  8. rabbitmq系统学习(二)

    Rabbitmq高级整合应用 RabbitMq整合Spring AMQP实战 RabbitAdmin 使用RabbitTemplate的execute方法执行对应操作 rabbitAdmin.decl ...

  9. golang IO streaming

    IO Streaming Streaming IO in Go,引用此文,略有修改 io.Reader和io.Writer io.Reader接口定义了从传输缓存读取数据 type Reader in ...

  10. Python——爬虫进阶

    课程内容 Python爬虫——反爬 Python加密与解密 Python模块——HashLib与base64    Python爬虫——selenium模块 Python——pytessercat识别 ...