文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何使用C#基于WebSocket实现聊天室功能

2023-06-29 04:00

关注

这篇文章将为大家详细讲解有关如何使用C#基于WebSocket实现聊天室功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

ServerHelper:

using System;using System.Collections;using System.Text;using System.Security.Cryptography; namespace SocketDemo{    // Server助手 负责:1 握手 2 请求转换 3 响应转换    class ServerHelper    {        /// <summary>        /// 输出连接头信息        /// </summary>        public static string ResponseHeader(string requestHeader)        {            Hashtable table = new Hashtable();             // 拆分成键值对,保存到哈希表            string[] rows = requestHeader.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);            foreach (string row in rows)            {                int splitIndex = row.IndexOf(':');                if (splitIndex > 0)                {                    table.Add(row.Substring(0, splitIndex).Trim(), row.Substring(splitIndex + 1).Trim());                }            }             StringBuilder header = new StringBuilder();            header.Append("HTTP/1.1 101 Web Socket Protocol Handshake\r\n");            header.AppendFormat("Upgrade: {0}\r\n", table.ContainsKey("Upgrade") ? table["Upgrade"].ToString() : string.Empty);            header.AppendFormat("Connection: {0}\r\n", table.ContainsKey("Connection") ? table["Connection"].ToString() : string.Empty);            header.AppendFormat("WebSocket-Origin: {0}\r\n", table.ContainsKey("Sec-WebSocket-Origin") ? table["Sec-WebSocket-Origin"].ToString() : string.Empty);            header.AppendFormat("WebSocket-Location: {0}\r\n", table.ContainsKey("Host") ? table["Host"].ToString() : string.Empty);             string key = table.ContainsKey("Sec-WebSocket-Key") ? table["Sec-WebSocket-Key"].ToString() : string.Empty;            string magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";            header.AppendFormat("Sec-WebSocket-Accept: {0}\r\n", Convert.ToBase64String(SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(key + magic))));             header.Append("\r\n");             return header.ToString();        }         /// <summary>        /// 解码请求内容        /// </summary>        public static string DecodeMsg(Byte[] buffer, int len)        {            if (buffer[0] != 0x81                || (buffer[0] & 0x80) != 0x80                || (buffer[1] & 0x80) != 0x80)            {                return null;            }            Byte[] mask = new Byte[4];            int beginIndex = 0;            int payload_len = buffer[1] & 0x7F;            if (payload_len == 0x7E)            {                Array.Copy(buffer, 4, mask, 0, 4);                payload_len = payload_len & 0x00000000;                payload_len = payload_len | buffer[2];                payload_len = (payload_len << 8) | buffer[3];                beginIndex = 8;            }            else if (payload_len != 0x7F)            {                Array.Copy(buffer, 2, mask, 0, 4);                beginIndex = 6;            }             for (int i = 0; i < payload_len; i++)            {                buffer[i + beginIndex] = (byte)(buffer[i + beginIndex] ^ mask[i % 4]);            }            return Encoding.UTF8.GetString(buffer, beginIndex, payload_len);        }         /// <summary>        /// 编码响应内容        /// </summary>        public static byte[] EncodeMsg(string content)        {            byte[] bts = null;            byte[] temp = Encoding.UTF8.GetBytes(content);            if (temp.Length < 126)            {                bts = new byte[temp.Length + 2];                bts[0] = 0x81;                bts[1] = (byte)temp.Length;                Array.Copy(temp, 0, bts, 2, temp.Length);            }            else if (temp.Length < 0xFFFF)            {                bts = new byte[temp.Length + 4];                bts[0] = 0x81;                bts[1] = 126;                bts[2] = (byte)(temp.Length & 0xFF);                bts[3] = (byte)(temp.Length >> 8 & 0xFF);                Array.Copy(temp, 0, bts, 4, temp.Length);            }            else            {                byte[] st = System.Text.Encoding.UTF8.GetBytes(string.Format("暂不处理超长内容").ToCharArray());            }            return bts;        }    }}

Server:

using System;using System.Collections.Generic;using System.Text;using System.Net;using System.Net.Sockets; namespace SocketDemo{    class ClientInfo    {        public Socket Socket { get; set; }        public bool IsOpen { get; set; }        public string Address { get; set; }    }     // 管理Client    class ClientManager    {        static List<ClientInfo> clientList = new List<ClientInfo>();        public static void Add(ClientInfo info)        {            if (!IsExist(info.Address))            {                clientList.Add(info);            }        }        public static bool IsExist(string address)        {            return clientList.Exists(item => string.Compare(address, item.Address, true) == 0);        }        public static bool IsExist(string address, bool isOpen)        {            return clientList.Exists(item => string.Compare(address, item.Address, true) == 0 && item.IsOpen == isOpen);        }        public static void Open(string address)        {            clientList.ForEach(item =>            {                if (string.Compare(address, item.Address, true) == 0)                {                    item.IsOpen = true;                }            });        }        public static void Close(string address = null)        {            clientList.ForEach(item =>            {                if (address == null || string.Compare(address, item.Address, true) == 0)                {                    item.IsOpen = false;                    item.Socket.Shutdown(SocketShutdown.Both);                }            });        }        // 发送消息到ClientList        public static void SendMsgToClientList(string msg, string address = null)        {            clientList.ForEach(item =>            {                if (item.IsOpen && (address == null || item.Address != address))                {                    SendMsgToClient(item.Socket, msg);                }            });        }        public static void SendMsgToClient(Socket client, string msg)        {            byte[] bt = ServerHelper.EncodeMsg(msg);            client.BeginSend(bt, 0, bt.Length, SocketFlags.None, new AsyncCallback(SendTarget), client);        }        private static void SendTarget(IAsyncResult res)        {            //Socket client = (Socket)res.AsyncState;            //int size = client.EndSend(res);        }    }     // 接收消息    class ReceiveHelper    {        public byte[] Bytes { get; set; }        public void ReceiveTarget(IAsyncResult res)        {            Socket client = (Socket)res.AsyncState;            int size = client.EndReceive(res);            if (size > 0)            {                string address = client.RemoteEndPoint.ToString(); // 获取Client的IP和端口                string stringdata = null;                if (ClientManager.IsExist(address, false)) // 握手                {                    stringdata = Encoding.UTF8.GetString(Bytes, 0, size);                    ClientManager.SendMsgToClient(client, ServerHelper.ResponseHeader(stringdata));                    ClientManager.Open(address);                }                else                {                    stringdata = ServerHelper.DecodeMsg(Bytes, size);                }                if (stringdata.IndexOf("exit") > -1)                {                    ClientManager.SendMsgToClientList(address + "已从服务器断开", address);                    ClientManager.Close(address);                    Console.WriteLine(address + "已从服务器断开");                    Console.WriteLine(address + " " + DateTimeOffset.Now.ToString("G"));                    return;                }                else                {                    Console.WriteLine(stringdata);                    Console.WriteLine(address + " " + DateTimeOffset.Now.ToString("G"));                    ClientManager.SendMsgToClientList(stringdata, address);                }            }            // 继续等待            client.BeginReceive(Bytes, 0, Bytes.Length, SocketFlags.None, new AsyncCallback(ReceiveTarget), client);        }    }     // 监听请求    class AcceptHelper    {        public byte[] Bytes { get; set; }         public void AcceptTarget(IAsyncResult res)        {            Socket server = (Socket)res.AsyncState;            Socket client = server.EndAccept(res);            string address = client.RemoteEndPoint.ToString();             ClientManager.Add(new ClientInfo() { Socket = client, Address = address, IsOpen = false });            ReceiveHelper rs = new ReceiveHelper() { Bytes = this.Bytes };            IAsyncResult recres = client.BeginReceive(rs.Bytes, 0, rs.Bytes.Length, SocketFlags.None, new AsyncCallback(rs.ReceiveTarget), client);            // 继续监听            server.BeginAccept(new AsyncCallback(AcceptTarget), server);        }    }     class Program    {        static void Main(string[] args)        {            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            server.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 200)); // 绑定IP+端口            server.Listen(10); // 开始监听             Console.WriteLine("等待连接...");             AcceptHelper ca = new AcceptHelper() { Bytes = new byte[2048] };            IAsyncResult res = server.BeginAccept(new AsyncCallback(ca.AcceptTarget), server);             string str = string.Empty;            while (str != "exit")            {                str = Console.ReadLine();                Console.WriteLine("ME: " + DateTimeOffset.Now.ToString("G"));                ClientManager.SendMsgToClientList(str);            }            ClientManager.Close();            server.Close();        }    }}

Client:

<!DOCTYPE html><script>    var mySocket;    function Star() {        mySocket = new WebSocket("ws://127.0.0.1:200", "my-custom-protocol");        mySocket.onopen = function Open() {            Show("连接打开");        };        mySocket.onmessage = function (evt) {            Show(evt.data);        };        mySocket.onclose = function Close() {            Show("连接关闭");            mySocket.close();        };    }    function Send() {        var content = document.getElementById("content").value;        Show(content);        mySocket.send(content);    }    function Show(msg) {        var roomContent = document.getElementById("roomContent");        roomContent.innerHTML = msg + "<br/>" + roomContent.innerHTML;    }</script><html><head>    <title></title></head><body>    <div id="roomContent" style="width: 500px; height: 200px; overflow: hidden; border: 2px solid #686868;        margin-bottom: 10px; padding: 10px 0px 0px 10px;">    </div>    <div>        <textarea id="content" cols="50" rows="3" ></textarea>    </div>    <input type="button" value="Connection" οnclick="Star()" />    <input type="button" value="Send" οnclick="Send()" /></body></html>

关于“如何使用C#基于WebSocket实现聊天室功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯