我目前正在测试一些基本的websocket示例,这些示例对我的基本知识没有完全帮助。我知道如何用C#在服务器上创建一个监听器,并将请求升级为web套接字。我需要帮助检索从javascript发送到服务器的字符串。
C#代码:
class Program
{
private static void ThreadProc(object obj)
{
var client = (TcpClient)obj;
var address = client.Client.RemoteEndPoint.ToString().Split(':');
Console.WriteLine(String.Format("A client is connected from {0}", address[0]));
NetworkStream stream = client.GetStream();
//enter to an infinite cycle to be able to handle every change in stream
while (true)
{
while (!stream.DataAvailable) ;
Byte[] bytes = new Byte[client.Available];
stream.Read(bytes, 0, bytes.Length);
//translate bytes of request to string
String data = Encoding.UTF8.GetString(bytes);
if (new Regex("^GET").IsMatch(data))
{
Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + Environment.NewLine
+ "Connection: Upgrade" + Environment.NewLine
+ "Upgrade: websocket" + Environment.NewLine
+ "Sec-WebSocket-Accept: " + Convert.ToBase64String(
SHA1.Create().ComputeHash(
Encoding.UTF8.GetBytes(
new Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
)
)
) + Environment.NewLine
+ Environment.NewLine);
stream.Write(response, 0, response.Length);
}
else
{
Console.WriteLine(data);
}
}
}
static void Main(string[] args)
{
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);
server.Start();
Console.WriteLine("Server has started on 127.0.0.1:80.{0}Waiting for a connection...", Environment.NewLine);
while (true)
{
var clientConnection = server.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(ThreadProc, clientConnection);
}
}
}
用于连接到websocket的Javascript。
var host = window.location.origin.replace("http", "ws");
var socket = new WebSocket("ws://127.0.0.1:80");
socket.onopen = function (openEvent) {
console.log("Socket connection is open.");
sendTextMessage();
};
function sendTextMessage() {
if (socket.readyState != WebSocket.OPEN)
{
console.log("Socket is not open for connection.");
return;
}
socket.send("MDN");
}
更新我现在可以看到消息了。然而,我没有得到字符串MDN,我得到了一些时髦的字符回来。更新了我的C#代码以显示更改。
我只是简单地尝试将javascript中的一个字符串发送到服务器,并在控制台上读取该字符串。如果有人能更多地解释如何同时连接多个网络浏览器,那将是非常棒的。此外,如果有人可以指示我将消息发送回所有连接的网络浏览器,请这样做。
如果这是重复的,请给我指正确的方向。
问题:"同时连接的多个web浏览器";
while(serverIsOn){
TcpClient cliTemp = server.AcceptTcpClient();
NetworkStream netTemp = cliTemp.GetStream();
Client cli = new Client(Necessary attributes);
clientsList.Add(cli);
}
每次获得一个连接时,都将每个属性放入一个新对象(创建类Client)中,该对象具有响应/接收该客户端示例所需的属性(TcpClient、NetworkStream、clientName…)
[另一个线程]通过客户端列表和调用Read:之前的新循环
循环(客户端列表)
if(cli.networkStream.DataAvailable){ cli.networkStream.Read(buffer, 0, buffer.Lenght); }
问题"更新我现在可以看到消息了。然而,我没有得到字符串MDN,我得到了一些时髦的字符回来。更新了我的C#代码以显示更改"我想你是在学习这个教程https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_server
它说,来自JavaScript的消息响应包含某些比特,这些比特指示消息是否是最终消息,消息有多长,以及解码消息的关键代码。这里有一个小解决方案:
public byte[] javaScriptUser(Byte[] data)
{
//encoded[1] => size of msg
Byte[] encoded = new Byte[((int)data[1] - 128)];
Array.Copy(data, 6, encoded, 0, encoded.Length);
Byte[] decoded = new Byte[((int)data[1] - 128)];
//KeyCode positions
Byte[] key = new Byte[4] { data[2], data[3], data[4], data[5] };
for (int i = 0; i < encoded.Length; i++)
{
decoded[i] = (Byte)(encoded[i] ^ key[i % 4]);
}
Array.Copy(decoded, data, decoded.Length);
return decoded;
}
不包括此部分!("如果是126,后面的2个字节(16位无符号整数),如果是127,后面的8个字节(64位无符号整数值)是长度")最后一部分有点乱,只花了几分钟就完成了,但我相信你可以做得更好。