使用C#创建websocket

文章目录[x]
  1. 0.1:一、使用.net框架内置方法
  2. 0.2:二、使用Fleck
  3. 0.3:三、其他Websocket框架
  4. 0.4:四、测试

一、使用.net框架内置方法

1. 创建一个基类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading.Tasks;
using System.Threading;


namespace WebSockets
{
    public class WebSocketBase
    {
        public static void Send(WebSocket ws,string content)
        {
            try
            {
                ArraySegment<byte> array = new ArraySegment<byte>(Encoding.UTF8.GetBytes(content));
                var task = ws.SendAsync(array, WebSocketMessageType.Text, true, CancellationToken.None);
                task.Wait();//异步改成同步
            }
            catch
            {
                ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
            }
        }


        public static string Receive(WebSocket ws)
        {
            try
            {
                //8kb的缓存区
                byte[] b = new byte[1024 * 8];
                ArraySegment<byte> buffer = new ArraySegment<byte>(b);
                var task = ws.ReceiveAsync(buffer, CancellationToken.None);
                task.Wait();
                return Encoding.UTF8.GetString(buffer.Array);
            }
            catch (Exception e)
            {
                ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
            }
            return null;
        }
    }
}

2.创建WebsocketService类。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net.WebSockets;
using System.Net;

namespace WebSockets
{
    public class MyWebSocketService:WebSocketBase
    {
        HttpListener httpListener;
        //客户端socket集合
        public Dictionary<int, WebSocket> _clientDic = new Dictionary<int, WebSocket>();
        public event EventHandler<int> OnConnect;
        public event EventHandler<string> DataReceive;
        public void Listening()
        {
            httpListener = new HttpListener();
            httpListener.Prefixes.Add("http://127.0.0.1:8888/");
            httpListener.Start();
            Task.Run(() =>
            {
                while(true)
                {
                    var httpListenerContext = httpListener.GetContext();
                    var webSocketContext = httpListenerContext.AcceptWebSocketAsync(null);
                    var _ws = webSocketContext.Result.WebSocket;
                    int id = webSocketContext.Id;
                    _clientDic.Add(id, _ws);
                    OnConnect?.Invoke(_ws,id);
                    Task.Run(() =>
                    {
                        while (_ws.State == WebSocketState.Open)
                        {
                            DataReceive?.Invoke(_ws, Receive(_ws));
                        }
                    });
                }
            });
        }

        public void SendMsg( WebSocket ws,string content)
        {
            Send(ws, content);
        }

        public void BroadcostMsg(string content)
        {
            foreach(var i in _clientDic)
            {
                Send(i.Value, content);
            }
        }
    }
}
3. 创建WebsocketClient类。
using System;
using System.Net.WebSockets;
using System.Threading.Tasks;
using System.Threading;

namespace WebSockets
{
    public class MyWebSocketClient:WebSocketBase
    {
        static ClientWebSocket _cws;
        public event EventHandler<string> DataReceive;

        public MyWebSocketClient()
        {
            _cws = new ClientWebSocket();
        }
        public void Connect(string uriStr)
        {
            var task = _cws.ConnectAsync(new Uri(uriStr), CancellationToken.None);
            task.Wait();
            Task.Run(() =>
            {
                while(true)
                {
                    string data = Receive(_cws);
                    DataReceive?.Invoke(_cws,data);
                }
            });
        }

        public void Close()
        {
            _cws.CloseAsync(WebSocketCloseStatus.NormalClosure, "normal close", CancellationToken.None);
        }

        public void SendMsg(string content)
        {
            Send(_cws, content);
        }
    }
}

二、使用Fleck

1. 使用Nuget安装Fleck或从Github上下载源码后编译。
2. 在项目中添加引用。
3. 示例:
using System;
using System.Collections.Generic;
using System.Linq;
using Fleck;

namespace WSFramework_Fleck
{
    class Program
    {
        static void Main(string[] args)
        {
            FleckLog.Level = LogLevel.Debug;
            var allSockets = new List<IWebSocketConnection>();
            var server = new WebSocketServer("ws://0.0.0.0:8888");
            server.Start(socket => {
                //客户端连接上服务端,则在socket列表添加一个客户端
                socket.OnOpen = () => {
                    Console.WriteLine("Open!");
                    allSockets.Add(socket);
                };
                //客户端主动关闭,则从socket列表删除这个客户端
                socket.OnClose = () => {
                    Console.WriteLine("Close!");
                    allSockets.Remove(socket);
                };
                //接收文本消息
                socket.OnMessage = message =>
                {
                    Console.WriteLine(message);
                    //给发送消息的客户端回复一条消息
                    socket.Send("Echo:" + message);
                };
                //接收二进制消息
                socket.OnBinary = b =>
                {

                };
            });

            var input = Console.ReadLine();
            //给所有客户端发送消息
            while (input != "exit")
            {
                foreach (var socket in allSockets.ToList())
                {
                    socket.Send(input);
                }
                input = Console.ReadLine();
            }
        }
    }
}

三、其他Websocket框架

TouchSocket https://rrqm_home.gitee.io/touchsocket/

四、测试

1. 方式一 浏览器打开控制台,注入脚本。
var socket = new WebSocket("ws://172.0.0.1:8888");  
socket.onopen = function(){
    //打开
}
socket.onmessage = function(e){
    alert("收到消息:"+e.data);
}
socket.onclose = function(){
    //关闭WebSocket
}
socket.onerror = function(){
    //错误触发
}

2. 方式二 websocket在线测试 http://www.websocket-test.com/

点赞

发表回复

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像(已失效)