C# 搭建WebSocket(服务端)

C# 搭建WebSocket(服务端)

第一篇博客,简要介绍一下用SuperWebSocket搭建WebSocket的服务端

依赖NuGet包 - SuperWebSocket

做了一个WebSocket的Demo,但是我不建议用 SuperWebSocket实现 ,原因有几个,如果有别的更好用的框架,也请大家留言。(肯定是有的,只是我现在没时间去研究)
SuperWebSocket 个人观点:

  1. 内嵌了log4net ,这点我不太喜欢。(如果再次导入log4net要注意引用)
  2. 版本也比较老旧,13年后没更新过。
  3. 仅支持Framework 4.5以上版本。

使用SuperWebSocket纯属为了达到效果。

代码

using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Config;
using SuperSocket.SocketEngine;
using SuperWebSocket;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

/// <summary>
/// 服务端实例
/// </summary>
public WebSocketServer WebSocket;
/// <summary>
/// 客户端实例
/// </summary>
WebSocketSession session;

bool OpenServer(int port, string serverName, bool isUseCertificate = false, string serverStoreName = "", string serverSecurity = "", string serverThumbprint = "")
{
 	WebSocket = new WebSocketServer();
    var serverConfig = new ServerConfig
    {
        Name = serverName,
        MaxConnectionNumber = 10000, //最大允许的客户端连接数目,默认为100。
        Mode = SocketMode.Tcp,
        Port = port, //服务器监听的端口。
        ClearIdleSession = false,   //true或者false, 是否清除空闲会话,默认为false。
        ClearIdleSessionInterval = 120,//清除空闲会话的时间间隔,默认为120,单位为秒。
        ListenBacklog = 10,
        ReceiveBufferSize = 64 * 1024, //用于接收数据的缓冲区大小,默认为2048。
        SendBufferSize = 64 * 1024,   //用户发送数据的缓冲区大小,默认为2048。
        KeepAliveInterval = 1,     //keep alive消息发送时间间隔。单位为秒。
        KeepAliveTime = 60,    //keep alive失败重试的时间间隔。单位为秒。
        SyncSend = false
    };
    bool isSetuped = false;
    SocketServerFactory socketServerFactory = null;
    //开启wss 使用证书
    if (isUseCertificate)
    {
        serverConfig.Security = serverSecurity;
        serverConfig.Certificate = new SuperSocket.SocketBase.Config.CertificateConfig
        {
            StoreName = serverStoreName,
            StoreLocation = System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine,
            Thumbprint = serverThumbprint
        };
        socketServerFactory = new SocketServerFactory();
    }
    isSetuped = this.WebSocket.Setup(new RootConfig(), serverConfig, socketServerFactory);
    if (isSetuped)
    {
		Console.WriteLine("打开成功");
    }
    else
    {
        Console.WriteLine("打开失败");
    }
    this.WebSocket.NewSessionConnected += NewSessionConnected;
    this.WebSocket.NewMessageReceived += NewMessageReceived;
    this.WebSocket.SessionClosed += SessionClosed;
    isSetuped = this.WebSocket.Start();
    if (isSetuped)
    {
        Console.WriteLine("启动成功...");
        setText("Server Listen at " + this.WebSocket.Listeners[0].EndPoint.Port.ToString());
        this._isRunning = true;
        this._thread = new Thread(new ThreadStart(ProcessMaintainance));
        this._thread.Start();
    }
    else
    {
        Console.WriteLine("启动失败");
    }
    return isSetuped;
}

/// <summary>
/// 新链接触发事件
/// </summary>
/// <param name="session"></param>
void NewSessionConnected(WebSocketSession session)
{
    try
    {
        this.session = session;//获取新连接的客户端
        string message = string.Format("New Session Connected:{0}, Path:{1}, Host:{2}, IP:{3}",
            session.SessionID.ToString(), session.Path, session.Host, session.RemoteEndPoint);
        Console.WriteLine("新链接" + message);
        NewConnected?.Invoke(session);

    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

/// <summary>
/// 客户端链接关闭触发事件
/// </summary>
/// <param name="session"></param>
/// <param name="value"></param>
void SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value)
{
    string message = string.Format("Session Close:{0}, Path:{1}, IP:{2}", value.ToString(), session.Path, session.RemoteEndPoint);
    Console.WriteLine(message);
    Closed?.Invoke(session);
}

/// <summary>
/// 后台线程,输出连接客户端
/// </summary>
void ProcessMaintainance()
{
    do
    {
        try
        {
            Console.WriteLine("Display Session Info:" + this.WebSocket.SessionCount);
            foreach (WebSocketSession session in this.WebSocket.GetAllSessions())
            {
                string message = string.Format("ID:{0}, Remote:{1}, Path:{2}, LastActiveTime:{3}, StartTime:{4}",
                    session.SessionID, session.RemoteEndPoint, session.Path
                  , session.LastActiveTime, session.StartTime);
                Console.WriteLine(message);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
        System.Threading.Thread.Sleep(5 * 60000);
    } while (this._isRunning);
}

/// <summary>
/// 发送消息
/// </summary>
/// <param name="session">客户端连接</param>
/// <param name="message">消息内容</param>
void SendMessage(WebSocketSession session, string message)
{
    Task.Factory.StartNew(() => { if (session != null && session.Connected) session.Send(message); });
}

/// <summary>
/// 发送消息
/// </summary>
/// <param name="session">客户端连接</param>
/// <param name="message">消息内容</param>
void SendMessage(WebSocketSession session, byte[] message)
{
    Task.Factory.StartNew(() => { if (session != null && session.Connected) session.Send(message, 0, message.Length); });
}

/// <summary>
/// 消息触发事件
/// </summary>
/// <param name="session"></param>
/// <param name="value"></param>
void NewMessageReceived(WebSocketSession session, string value)
{
    try
    {
        Console.WriteLine("Receive:" + value.ToString() + " ClientIP:" + session.RemoteEndPoint);
        if (value.ToString().Equals("IsHere**"))//客户端定时发送心跳,维持链接
        {
            return;
        }
        else
        {
            MessageReceived?.Invoke(session, value.ToString());
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

WebSocket在线测试地址:
http://www.websocket-test.com/

效果图:

启动服务端
效果图

调用代码

/// <summary>
/// 点击发送
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button2_Click(object sender, EventArgs e)
{
     SendMessage(this.session, "你好,这里是8000端口");
 }

/// <summary>
/// 启动服务器
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button1_Click(object sender, EventArgs e)
{
   OpenServer(8000, "127.0.0.1");
}
  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值