一步一步学WebSocket(二) 使用SuperWebSocket实现自己的服务端

  上一篇文章,我们了解了客户端如何与服务器创建WebSocket连接。但是一个巴掌拍不响,既然是通信,就必然最少要有两个端。今天我们来看看c#如何用已有的框架实现一个WebSocket服务端。

  在.Net Framework
4.5及以上版本中,微软为我们集成了WebSocket协议的基本实现。微软提供的WebSocket对象位于System.Net.WebSocket命名空间下,使用起来挺繁琐的,所以我选择了SuperWebSocket框架来简化开发的难度。

  SuperWebSocket框架可以通过NuGet直接获取并引用到项目中,也可以在http://superwebsocket.codeplex.com/中下载最新的DLL

  我们来看SuperWebSocket如何我们快速搭建一个服务端

  

WebSocketServer wsServer = new WebSocketServer();

if (!wsServer.Setup("127.0.0.1", 2012))
{
//设置IP 与 端口失败 通常是IP 和端口范围不对引起的 IPV4 IPV6
}

if (!wsServer.Start())
{
//开启服务失败 基本上是端口被占用或者被 某杀毒软件拦截造成的
return;
}

wsServer.NewSessionConnected += (session) =>
{
//有新的连接
};
wsServer.SessionClosed += (session, reason) =>
{
//有断开的连接
};
wsServer.NewMessageReceived += (session, message) =>
{
//接收到新的文本消息
};
wsServer.NewDataReceived += (session, bytes) =>
{
//接收到新的二进制消息
};

Console.ReadKey();

wsServer.Stop();

  这里WebSocketServer对象通过Setup方式对要侦听的IP及端口进行了设置。然后使用Start方法启动侦听。

  Setup方法有4种重载,但是我们通常用到的只有设置IP和端口,IP为string类型,如果传入的字符串无法被转换为支持的IP格式,Setup方法会返回false表示设置失败。

  WebSocketServer还提供了4个事件用以管理与客户端的连接、断开、和接受消息动作。新版本的WebSocket支持传送的数据格式有 “文本”
和 “二进制”两种,NewMessageReceived事件用于处理文本类型的消息,NewDataReceived事件用于处理二进制类型的消息。

  

  到这里 我们已经成功的搭建了一个实现了WebSocket协议的服务端了。至于服务端的寄宿方式有很多,SuperWebSocket框架支持以
控制台、Winform、IIS以及Windows服务的形式寄宿服务,不过网上很多资料都不建议在IIS中寄宿服务,据说是因为寄宿在IIS中性能比较低。

  WebSocket既然是双工通信,那么我们就不能光等着接收来自客户端的消息,
我们也需要从服务端向客户端“推送”消息,现在我们来看如何由服务端向客户端发送消息。

  SuperWebSocket框架中,服务端与客户端创建的连接对象为WebSocketSession类型,也就是说它将每一个客户端的实例视为一个会话,在客户端创建连接的时候,产生这个会话,在客户端断开连接的时候,销毁这个会话,而客户端与服务端进行消息通信的时候,也依赖这个会话进行传递。我们要实现服务器端向客户端的广播,就要获取到当前正在活动的所有会话,我们通过代码来看如何获取所有的会话

  


 wsServer.GetAllSessions() //获取所有的会话 已断开的会话不会出现在集合中

  很简单吧,在获取到活动的会话之后 我们就可以向客户端发送消息了,这里我们让服务器向客户端定时发送服务器时间


Timer timer = new Timer((data) =>
{
var msg = string.Format("服务器当前时间:{0:HH:MM:ss}", DateTime.Now);

//对当前已连接的所有会话进行广播
foreach (var session in wsServer.GetAllSessions())
{
session.Send(msg);
}

}, null, 1000, 1000);

  这样 所有与服务端保持连接的客户端就都可以接受到来自服务器端的消息了。

  在这个例子里 我们看到了所有的消息都是由会话对象发出的,会话对象Send的消息
也支持“文本”与“二进制两种形式,同时会话对象还提供一个SendCloseHandshakeResponse()方法向客户端发送一个强制断开连接的指令。

  WebSocketSession对象包含了服务端和客户端的所有信息,以及WebSocketServer对象本身,我们可以利用它做很多事情,下边我们就来实现一个简单的聊天室。至于聊天室的原理
就是一个人将要说的话发送到服务器,再由服务器广播给在这个聊天室里的所有人看到。恩 就这么简单。我们来上代码,多了不解释,相当简单。

  

 public class ChatWebSocket
{
private const string ip = "127.0.0.1";
private const int port = 2014;
private WebSocketServer ws = null;//SuperWebSocket中的WebSocketServer对象

public ChatWebSocket()
{
ws = new WebSocketServer();//实例化WebSocketServer

//添加事件侦听
ws.NewSessionConnected += ws_NewSessionConnected;//有新会话握手并连接成功
ws.SessionClosed += ws_SessionClosed;//有会话被关闭 可能是服务端关闭 也可能是客户端关闭
ws.NewMessageReceived += ws_NewMessageReceived;//有客户端发送新的消息
}

void ws_NewSessionConnected(WebSocketSession session)
{
Console.WriteLine("{0:HH:MM:ss} 与客户端:{1}创建新会话", DateTime.Now, GetSessionName(session));
var msg = string.Format("{0:HH:MM:ss} {1} 进入聊天室", DateTime.Now, GetSessionName(session));
SendToAll(session, msg);
}

void ws_SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value)
{
Console.WriteLine("{0:HH:MM:ss} 与客户端:{1}的会话被关闭 原因:{2}", DateTime.Now, GetSessionName(session), value);
var msg = string.Format("{0:HH:MM:ss} {1} 离开聊天室", DateTime.Now, GetSessionName(session));
SendToAll(session, msg);
}
void ws_NewMessageReceived(WebSocketSession session, string value)
{
var msg = string.Format("{0:HH:MM:ss} {1}说: {2}", DateTime.Now, GetSessionName(session), value);

SendToAll(session, msg);

}
/// <summary>
/// 启动服务
/// </summary>
/// <returns></returns>
public void Start()
{
if (!ws.Setup(ip, port))
{
Console.WriteLine("ChatWebSocket 设置WebSocket服务侦听地址失败");
return;
}

if (!ws.Start())
{
Console.WriteLine("ChatWebSocket 启动WebSocket服务侦听失败");
return;
}

Console.WriteLine("ChatWebSocket 启动服务成功");

}

/// <summary>
/// 停止侦听服务
/// </summary>
public void Stop()
{

if (ws != null)
{
ws.Stop();
}
}

private string GetSessionName(WebSocketSession session)
{
//这里用Path来取Name 不太科学……
return HttpUtility.UrlDecode(session.Path.TrimStart(‘/‘));
}

private void SendToAll(WebSocketSession session, string msg)
{
//广播
foreach (var sendSession in session.AppServer.GetAllSessions())
{
sendSession.Send(msg);
}
}
}

  关与SuperWebSocket的基本使用就介绍到这里了……顶着老板不时窥屏的压力,可能文章有点语无伦次,希望大家多多体谅,也希望大家提出宝贵意见
共同学习。下一篇我会考虑介绍“子协议”和SuperWebSocket提供的Json字符串类型数据的处理

示例代码在这里   下载

一步一步学WebSocket(二) 使用SuperWebSocket实现自己的服务端,布布扣,bubuko.com

时间: 2024-10-11 19:09:51

一步一步学WebSocket(二) 使用SuperWebSocket实现自己的服务端的相关文章

hbase源码系列(十二)Get、Scan在服务端是如何处理?

继上一篇讲了Put和Delete之后,这一篇我们讲Get和Scan, 因为我发现这两个操作几乎是一样的过程,就像之前的Put和Delete一样,上一篇我本来只打算写Put的,结果发现Delete也可以走这个过程,所以就一起写了. Get 我们打开HRegionServer找到get方法.Get的方法处理分两种,设置了ClosestRowBefore和没有设置的,一般来讲,我们都是知道了明确的rowkey,不太会设置这个参数,它默认是false的. if (get.hasClosestRowBef

WebSocket安卓客户端实现详解(三)–服务端主动通知

WebSocket安卓客户端实现详解(三)–服务端主动通知 本篇依旧是接着上一篇继续扩展,还没看过之前博客的小伙伴,这里附上前几篇地址 WebSocket安卓客户端实现详解(一)–连接建立与重连 WebSocket安卓客户端实现详解(二)–客户端发送请求 终于是最后一篇啦,有点激动\ ( ≧▽≦ ) /啦啦啦, 服务端主动通知 热身完毕,我们先回顾下第一篇中讲到的服务端主动通知的流程 根据notify中事件类型找到对应的处理类,处理对应逻辑. 然后用eventbus通知对应的ui界面更新. 如果

通过WebSocket实现实时通讯C#语言编写服务端

无意中发现js有webSocket对象于是百度了一下客户端代码与服务端代码没有现成的 有的就有一些简单了连接例子有的还不好使 于是就自己整理了一下 c#编写的服务端代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Text.RegularExpression

(二)Netty学习笔记之服务端启动

本文将不会对netty中每个点分类讲解,而是一个服务端启动的代码走读,在这个过程中再去了解和学习,这也是博主自己的学习历程.下面开始正文~~~~ 众所周知,在写netty服务端应用的时候一般会有这样的启动代码: (代码一) 1 EventLoopGroup bossGroup = new NioEventLoopGroup(1); 2 EventLoopGroup workerGroup = new NioEventLoopGroup(); 3 try { 4 ServerBootstrap b

一步步学WebSocket(1)声明式WebSocket

本节描述声明式WebSocket编程,可以与后一篇编程式WebSocket作对比学习: 首先上服务端: @ServerEndpoint("/chat") public class DeclarativeServer {     @OnOpen       public void onOpen(Session session) {           System.out.println("Somebody is coming!");      }          

打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!

随着HTML5 WebSocket技术的日益成熟与普及,我们可以借助WebSocket来更加方便地打通BS与CS -- 因为B/S中的WebSocket可以直接连接到C/S的服务端,并进行双向通信.如下图所示: 一.对Socket Server的要求 我们可以尝试让Socket Server透明地支持WebSocket客户端,所谓透明的意思是,服务端开发人员不用关心客户端究竟是什么类型,而是可以统一的接收数据.处理数据.发送数据.为了做到这一点,我们可以构建一个服务端框架,让框架完成透明化的工作

Demo源码放送:打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!

随着HTML5 WebSocket技术的日益成熟与普及,我们可以借助WebSocket来更加方便地打通BS与CS -- 因为B/S中的WebSocket可以直接连接到C/S的服务端,并进行双向通信.如下图所示: 一.对Socket Server的要求 我们可以尝试让Socket Server透明地支持WebSocket客户端,所谓透明的意思是,服务端开发人员不用关心客户端究竟是什么类型,而是可以统一的接收数据.处理数据.发送数据.为了做到这一点,我们可以构建一个服务端框架,让框架完成透明化的工作

WebSocket 实现服务端给客户端推送消息

目录 代码发布 应用场景 ajax 操作 队列 递归 如何实现服务端主动给客户端推送消息的效果 长轮询(兼容性好) websocker(主流浏览器都支持) 代码验证(了解) 代码发布 服务端主动给客户端推送消息 截至目前为止,我们所写的 web 项目基本都是基于 HTTP 协议的 HTTP 协议有四大特性:无链接 基于 HTTP 协议实现服务端主动给客户端推送消息好像有点麻烦--- 我们都经历过,浏览器打开一个网站不动,网站过一会儿自动弹出消息 再比如网页版本的微信和 qq,我们所有人创建一个群

一步一步跟我学DeviceOne开发 - 仿微信应用(一,二,三)

这是一个系列的文档,长期目标是利用DeviceOne开发一些目前使用广泛的优质手机应用,我们会最大化的实现这些应用的每一个功能和细节,不只停留在简单的UI模仿和Demo阶段,而是一个基本可以使用的实际App. 在实现的过程中,会有很多困难,还会发现有一些功能目前缺乏组件支持而无法实现,也会碰见各种移动开发中都会碰到的常见技术问题.一步一步的操作和问题的解决可以让开发者直观的了解通过DeviceOne如何开发一个实际App,也可以了解移动开发本身的很多技术细节,可以让App开发者少走很多弯路. 这