首页 > 编程语言 >C# WebSocketSharp 框架的用法

C# WebSocketSharp 框架的用法

时间:2024-11-06 19:31:04浏览次数:1  
标签:C# void System private 用法 WebSocketSharp static using WebSockets

一、概述
WebSocketSharp 是一个 C# 实现 websocket 协议客户端和服务端,WebSocketSharp 支持RFC 6455;WebSocket客户端和服务器;消息压缩扩展;安全连接;HTTP身份验证;查询字符串,起始标题和Cookie;通过HTTP代理服务器连接;.NET Framework 3.5或更高版本(包括兼容环境,如Mono)。

github 地址

https://github.com/sta/websocket-sharp

二、服务器端

服务器端的代码量很少,这里我全部使用 winform 来展示。

新建一个 winform 项目,界面如下

新建一个类 ServerManager

using System;
using WebSocketSharp.Server;
 
internal class ServerManager
{
    private static WebSocketServer WebSocketServers = null;
 
    public static bool IsListening
    {
        get
        {
            if (WebSocketServers == null)
                return false;
            return WebSocketServers.IsListening;
        }
    }
 
    private static void Init()
    {
        WebSocketServers = new WebSocketServer(8888);
 
        //添加具有指定行为和路径的WebSocket服务
        //string 参数 表示要添加的服务的绝对路径
        WebSocketServers.AddWebSocketService<Laputa>("/Laputa");
    }
 
    public static void Open()
    {
        WebSocketServers.Start();
        Console.WriteLine("开启服务器");
    }
 
    public static void Close()
    {
        WebSocketServers.Stop();
        Console.WriteLine("关闭服务器");
    }
 
    static ServerManager()
    {
        Init();
    }
 
    private ServerManager() { }
}

新建一个类 Laputa,这个类相当于在 websocket 里面负责单独的模块,同样的,在客户端的访问链接也要配套。

using System;
using WebSocketSharp;
using WebSocketSharp.Server;
 
public class Laputa : WebSocketBehavior
{
    protected override void OnMessage(MessageEventArgs e)
    {
        Console.WriteLine("[OnMessage]" + e.Data);
 
        var msg = e.Data == "BALUS"
                  ? "Are you kidding?"
                  : "I'm not available now.";
        Send(msg);
    }
 
    protected override void OnOpen()
    {
        Console.WriteLine("[OnOpen]");
    }
 
    protected override void OnClose(CloseEventArgs e)
    {
        Console.WriteLine("[OnClose]" + e.Reason);
    }
 
    protected override void one rror(ErrorEventArgs e)
    {
        Console.WriteLine("[OnError]" + e.Message);
    }
}

OnMessage 是指收到客户端的消息

OnOpen 客户端连接到了当前的接口

OnClose 客户端断开了连接

OnError websocket 出现了错误

接下来就是 winform 界面的代码了

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WebSocketSharpServer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
 
        }
 
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (ServerManager.IsListening)
                ServerManager.Close();
        }
 
        private void Button_Open_Click(object sender, EventArgs e)
        {
            ServerManager.Open();
        }
 
        private void Button_Close_Click(object sender, EventArgs e)
        {
            ServerManager.Close();
        }
    }
}

服务器端的代码就这么多,其实还有其他的很多功能,SSL/TLS,Cookies,证书 等,有兴趣的可以参考 github 的文档。

using System;
using System.Threading.Tasks;
using WebSocketSharp;
 
/// <summary>
/// Websocket
/// </summary>
internal class NetManager
{
    #region 字段
 
    private static WebSocket WebSockets = null;
 
    private static int ConsoleCount = 0;
 
    private static System.Windows.Forms.Timer Timer = null;
 
    /// <summary>
    /// 当前的网络是否连接
    /// </summary>
    public static bool IsConnect
    {
        get
        {
            if (WebSockets == null)
                return false;
            return WebSockets.IsAlive;
        }
    }
 
    //这里ip地址可以从别的地方取值,因为用的 static 静态构造函数,
    //构造函数会调用 Init 方法,这会导致 IPAddress 为 null 就初始化完成了。
    /// <summary>
    /// websocket 的地址,一般以 ws://  或者 wss:// 开头
    /// </summary>
    public static string IPAddress { get; private set; } = "ws://127.0.0.1:8888/Laputa";
    /// <summary>
    /// 是否显示ping
    /// </summary>
    public static bool IsShowPingLog { get; set; } = false;
    /// <summary>
    /// 收到服务器消息的回调
    /// </summary>
    public static Action<string> OnMessage = null;
    /// <summary>
    /// 连接成功和断开连接的回调
    /// </summary>
    public static Action<bool> OnNetStateChange = null;
 
 
 
    #endregion
 
    #region 初始化
 
    private static void Init()
    {
        if (string.IsNullOrEmpty(IPAddress))
            return;
 
        WebSockets = new WebSocket(IPAddress);
 
        WebSockets.OnOpen += WebSockets_OnOpen;
        WebSockets.OnMessage += WebSockets_OnMessage;
        WebSockets.OnClose += WebSockets_OnClose;
        WebSockets.OnError += WebSockets_OnError;
 
        Console.WriteLine("[NetManager]初始化成功!");
 
        Timer = new System.Windows.Forms.Timer();//实例化Timer类,设置间隔时间(毫秒);
        Timer.Interval = 3000;
        Timer.Tick += Timer_Tick;//到达时间的时候执行事件
    }
 
    private static void Timer_Tick(object sender, EventArgs e)
    {
        if (!WebSockets.IsAlive) return;
 
        WebSockets.Send("ping");
 
        if (IsShowPingLog)
        {
            Console.WriteLine("ping");
 
            ConsoleCount++;
            if (ConsoleCount > 100)
            {
                ConsoleCount = 0;
                Console.Clear();
            }
        }
    }
 
    #endregion
 
    #region WebSocket 相关
 
    private static void WebSockets_OnOpen(object sender, EventArgs e)
    {
        Console.WriteLine("[NetManager][OnOpen] 时间:{0}", DateTime.Now);
        if (OnNetStateChange != null)
            OnNetStateChange(true);
    }
 
    private static void WebSockets_OnError(object sender, ErrorEventArgs e)
    {
        string message = string.Format("[NetManager][OnError]{0}", e.Message);
        Console.WriteLine(message);
    }
 
    private static void WebSockets_OnClose(object sender, CloseEventArgs e)
    {
        Console.WriteLine("[NetManager][OnClose]" + e.Reason);
 
        if (OnNetStateChange != null)
            OnNetStateChange(false);
 
        if (!string.IsNullOrEmpty(e.Reason) && !IsClose)
        {
            DisconnectionReconnects();//断线重连
        }
    }
 
    private static void WebSockets_OnMessage(object sender, MessageEventArgs e)
    {
        Console.WriteLine("[NetManager][OnMessage]" + e.Data);
 
        //心跳类型消息
        //if (e.IsPing)
        //{
        //    Console.WriteLine("ping");
        //    return;
        //}
 
        //字符串类型的消息
        if (e.IsText)
        {
            if (OnMessage != null) 
                OnMessage(e.Data);
            return;
        }
 
        //二进制消息
        if(e.IsBinary)
        {
            //二进制使用RawData
            Console.WriteLine(e.RawData);
            return;
        }
    }
 
    #endregion
 
    #region 服务器开关
 
    private static bool IsClose = false;
 
    /// <summary>
    /// 连接服务器
    /// </summary>
    /// <returns></returns>
    public static bool Connect()
    {
        if (WebSockets == null)
            return false;
        if (WebSockets.IsAlive)
            return false;
 
        WebSockets.Connect();
        //异步连接服务器
        //WebSockets.ConnectAsync();
        //是否接收ping
        //WebSockets.EmitOnPing = true;
 
        //连接状态可以参考枚举:ReadyState
        if (WebSockets.IsAlive)
        {
            IsClose = false;
            Timer.Enabled = true;
            return true;
        }
        return false;
    }
 
    /// <summary>
    /// 关闭服务器连接 
    /// </summary>
    /// <returns></returns>
    public static bool Disconnect()
    {
        if (WebSockets == null)
            return false;
 
        WebSockets.Close();
        //异步关闭
        //WebSockets.CloseAsync();
 
        Timer.Enabled = false;
        IsClose = true;
 
        return WebSockets.IsAlive == false;
    }
 
    #endregion
 
    #region 发送消息
 
    /// <summary>
    /// 发送消息
    /// </summary>
    /// <param name="message"></param>
    public static void Send(string message)
    {
        if (string.IsNullOrEmpty(message))
        {
            Console.WriteLine("[NetManager]发送的消息不能为空");
            return;
        }
        if (WebSockets == null || !WebSockets.IsAlive)
        {
            Console.WriteLine("[NetManager]请先打开服务器");
            return;
        }
 
        WebSockets.Send(message);
        //异步发送
        //completed 是一个委托,发送完成会调用
        //WebSockets.SendAsync(data, completed);
 
        Console.WriteLine("[NetManager]发送:" + message);
    }
 
    #endregion
 
    #region 断线重连
 
    //是否正在重新连接中  
    private static bool IsReconnectioning = false;
 
    private static async void DisconnectionReconnects()
    {
        if (IsReconnectioning) return;
 
        IsReconnectioning = true;
 
        while (true)
        {
            if (WebSockets.IsAlive)
            {
                Console.WriteLine("[NetManager]断线重连成功");
                IsReconnectioning = false;
                break;
            }
            if (IsClose)
            {
                Console.WriteLine("[NetManager]关闭连接不必断线重连");
                break;
            }
 
            Console.WriteLine("[NetManager]断线重连中......");
            WebSockets.Connect();
            //WebSockets.ConnectAsync();
            await Task.Delay(TimeSpan.FromSeconds(1));
        }
    }
 
    #endregion
 
    #region 构造函数
 
    static NetManager()
    {
        Init();
    }
 
    private NetManager() { }
 
    #endregion
}
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WebSocketSharpClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            NetManager.OnMessage = OnMessage;           
        }
 
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            NetManager.Disconnect();
        }
 
        private void OnMessage(string msg)
        {
            Console.WriteLine("收到消息:" + msg);
        }
 
        private void Button_Send_Click(object sender, EventArgs e)
        {
            string msg = TextBox_Content.Text;
            NetManager.Send(msg);
        }
 
 
        private void Button_Close_Click(object sender, EventArgs e)
        {
            NetManager.Disconnect();
        }
 
        private void Button_Connect_Click(object sender, EventArgs e)
        {
            NetManager.Connect();
        }
    }
}

来源:https://blog.csdn.net/qq_38693757/article/details/131286795

 

 

 

 

 



标签:C#,void,System,private,用法,WebSocketSharp,static,using,WebSockets
From: https://www.cnblogs.com/ywtssydm/p/18524556

相关文章

  • CF963-Div2-E. Xor-Grid Problem
    CF963-Div2-E.Xor-GridProblem题意给定一个\(n\timesm\)的矩阵\(a\),有两种操作:选择一行,把每个数变成所在列所有数的异或之和。选择一列,把每个数变成所在行所有数的异或之和。求进行任意次操作后整个矩阵最小的美丽值。思路第一个发现:同一数异或两次相当于没有异......
  • C# WebSocket的简单使用【使用Fleck实现】
    有bug,不推荐使用有bug,不推荐使用有bug,不推荐使用2.WebSocketHelper新建 WebSocketHelper.csusingFleck;namespaceWebSocket{internalclassWebSocketHelper{//客户端url以及其对应的Socket对象字典IDictionary<string,IWebSocketCon......
  • 零基础‘自外网到内网’渗透过程详细记录(cc123靶场)——上
    一、网络环境示意图二、环境搭建首先将三个虚拟机使用VMware打开。接下来对虚拟机进行配置。首先配置虚拟机“护卫神主机大师(项目四)”。点击编辑虚拟机设置。发现存在两个网卡。打开虚拟网络编辑器。点击更改设置。点击添加网络。选择VM19后点击确定。根......
  • c语言中多个变量连续赋值
     001、[root@PC1test]#lstest.c[root@PC1test]#cattest.c##测试c程序#include<stdio.h>intmain(void){inti,j;i=j=5;//连续赋值printf("i=%d\n",i);printf("j=%......
  • Scala的高阶函数
    在函数式编程中,高阶函数(Higher-OrderFunction)是核心概念之一,它们可以接受其他函数作为参数,或者返回函数作为结果358。这使得函数可以像普通值一样被传递和操作,从而实现更灵活和抽象的编程方式56。 在Scala中实现高阶函数1.作为参数的函数:在Scala中,函数可以作为参数传递给......
  • 第十届中国大学生程序设计竞赛 哈尔滨站(CCPC 2024 Harbin Site)
    B.ConcaveHull题目描述简单多边形是平面中由线段组成的闭合曲线,这些线段首尾相连,除了因连接共用的线段端点,任何两个线段都不能彼此相交。简单多边形可以分为两类:凸多边形和凹多边形。一个凸多边形是指:多边形中任意两点间的线段上的所有点都在多边形内,包括在内部或边界上。......
  • 对C++程序使用输入输出重定向
    一般来说,在VisualStudio使用文件重定向有三种方法:方法一:通过命令行参数实现项目→属性→配置属性→调试→命令参数然后就在这里加上你的命令行参数比如我有这样一段程序:#include<iostream>#include<fstream>#include"Sales_item.h"intmain(){ Sales_itemtrans1,......
  • Scala作业
    importscala.collection.mutable//1.创建一个可变Map,用于存储图书馆中的书籍信息(键为书籍编号,值为包含书籍名称、作者、库存数量的元组),初始化为包含几本你喜欢的书籍信息。//2.使用+=操作符添加两本新的书籍到图书馆集合中。//3.根据书籍编号查询某一本特定的书籍信......
  • 0基础学Python——面向对象-可迭代、面向对象-迭代器、call方法、call方法实现装饰器
    0基础学Python——面向对象-可迭代、面向对象-迭代器、call方法、call方法实现装饰器、计算函数运行时间面向对象--可迭代实现方法面向对象--迭代器实现方法call方法作用call方法实现装饰器代码演示计算函数运行时间代码演示面向对象–可迭代把对象看做容器,存储......
  • 基于卷积神经网络的柑桔病害识别与防治系统,resnet50,mobilenet模型【pytorch框架+pytho
     更多目标检测和图像分类识别项目可看我主页其他文章功能演示:柑橘病害识别与防治系统,卷积神经网络,resnet50,mobilenet【pytorch框架,python源码】_哔哩哔哩_bilibili(一)简介基于卷积神经网络的柑桔病害识别与防治系是在pytorch框架下实现的,这是一个完整的项目,包括代码,数据集,......