欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#基于WebSocket實現(xiàn)聊天室功能

 更新時間:2022年02月12日 14:40:40   作者:Sean包子哥  
這篇文章主要為大家詳細介紹了C#基于WebSocket實現(xiàn)聊天室功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了C#基于WebSocket實現(xiàn)聊天室功能的具體代碼,供大家參考,具體內容如下

前面兩篇溫習了,C# Socket內容

本章根據(jù)Socket異步聊天室修改成WebSocket聊天室

WebSocket特別的地方是 握手和消息內容的編碼、解碼(添加了ServerHelper協(xié)助處理)

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);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? // 發(fā)送消息到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);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? // 繼續(xù)等待
? ? ? ? ? ? client.BeginReceive(Bytes, 0, Bytes.Length, SocketFlags.None, new AsyncCallback(ReceiveTarget), client);
? ? ? ? }
? ? }
?
? ? // 監(jiān)聽請求
? ? 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);
? ? ? ? ? ? // 繼續(xù)監(jiān)聽
? ? ? ? ? ? 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); // 開始監(jiān)聽
?
? ? ? ? ? ? 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" style="padding: 10px 0px 0px 10px;"></textarea>
? ? </div>
? ? <input type="button" value="Connection" οnclick="Star()" />
? ? <input type="button" value="Send" οnclick="Send()" />
</body>
</html>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

最新評論