私はWebSocketクライアントをJavascriptで書いています。これはC#my serverと接続して握手するものです。現在、出力ストリームを「フラッシュ」すると(ヘッダBACKをクライアントに送って接続を確認した後でのみ)、クライアントがクラッシュし、次回の書き込みを試みるときにサーバ側の例外が生成されます。後者の動作は予想されますが、私が理解できないことは、フラッシュによって接続が切断される理由です。私はTcpListenerと、サーバー側のStreamWriterを持つSocketと、クライアントのプレーンなWebSocketを使用しています。WebSocket接続がonmessageの前に破棄されます
「ハンドシェイク」の送信中にテキストが両方向に送信され、各行の送信後にFlushが実行されますが、ハンドシェイクが完了するとすぐにフラッシュが終了します接続。
このリビジョンに十分な情報がない場合は教えてください。それは数回修正されています。
ありがとうございます。
クライアントJavascriptを:
<!DOCTYPE html>
<meta charset="utf-8" />
<html>
<head>
<script language="javascript" type="text/javascript">
var wsUri = "ws://127.0.0.1:9002/cc";
var output;
var websocket = null;
function init()
{
StartWebSocket();
}
function StartWebSocket()
{
output = document.getElementById("output");
writeToScreen("#WebSocket Starting");
websocket = new WebSocket(wsUri,"lorem.ipsum.com");
writeToScreen("#WebSocket Instantiated");
websocket.removeEventListener("open",onOpen,false);
websocket.addEventListener("open",onOpen,false);
websocket.removeEventListener("close",onClose,false);
websocket.addEventListener("close",onClose,false);
websocket.removeEventListener("message",onMessage,false);
websocket.addEventListener("message",onMessage,false);
websocket.removeEventListener("error",onError,false);
websocket.addEventListener("error",onError,false);
writeToScreen("#WebSocket Events Attached");
}
function onOpen(evt)
{
try
{
writeToScreen("#WebSocket Connection Established");
writeToScreen("#WebSocket BinaryType: " + websocket.binaryType);
writeToScreen("#WebSocket Protocol: " + websocket.protocol);
writeToScreen("#WebSocket Extensions: " + websocket.extensions);
doSend("TestOutput\r\n\r");
}
catch(e)
{
writeToScreen(e);
}
}
function onClose(evt)
{
writeToScreen("#WebSocket Connection Aborted:");
writeToScreen(" Reason: " + evt.code);
writeToScreen(" Reason: " + evt.reason);
writeToScreen(" Clean: " + evt.wasClean);
}
function onMessage(evt)
{
writeToScreen("#WebSocket Message Event");
try
{
writeToScreen("<span style=\"color: blue;\">#WebSocket Server Message: " + evt.data+"</span>");
}
catch(e)
{
writeToScreen(e);
}
}
function onError(evt)
{
writeToScreen("<span style=\"color: red;\">#WebSocket Error:</span> " + evt.data);
}
function doSend(message)
{
try
{
websocket.send(message);
writeToScreen("#WebSocket Output Written to Server: " + message);
}
catch(e)
{
writeToScreen(e);
}
}
function writeToScreen(message)
{
try
{
var pre = document.createElement("a");
pre.style.wordWrap = "break-word";
pre.innerHTML = message + "<br>";
output.appendChild(pre);
}
catch(e)
{
writeToScreen(e);
}
}
window.addEventListener("load", init, false);
</script>
</head>
<body>
<div id="output"></div>
</body>
</html>
次のように私は私のクライアントから受け取るハンドシェイクオファーがある:
GET /cc HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 127.0.0.1:9002
Origin: http://localhost
Sec-WebSocket-Key: icajBpkAfgA+YbVheBpDsQ==
Sec-WebSocket-Version: 13
私はそうのようなハンドシェイクを解釈:
public override void Interpret(string Argument)
{
if (String.IsNullOrEmpty(Argument))
{
return;
}
else
{
if(!HeaderFinished)
{
if (!HeaderStarted)
{
if (Argument.StartsWith("GET /"))
{
this.Role = "client";
HeaderStarted = true;
this.Server.Print("Connection at " + this.Address + " set to client.");
}
else
{
return;
}
}
else
{
if (Argument.StartsWith("Sec-WebSocket-Key:"))
{
this.Key = Argument.Split(' ')[1].TrimEnd().TrimStart();
return;
}
else if (Argument.StartsWith("Sec-WebSocket-Version:"))
{
this.HeaderFinished = true;
this.WriteHeaderResponse();
HeaderSent = true;
return;
}
}
}
else
{
this.InterpretMessage(DecodeMessage(Argument));
return;
}
}
}
は私のヘッダーを送信応答:
public void WriteHeaderResponse()
{
this.WriteLine("HTTP/1.1 101 Switching Protocols");
this.WriteLine("Upgrade: websocket");
this.WriteLine("Connection: Upgrade");
String NewKey = ComputeResponseKey(this.Key);
this.WriteLine("Sec-WebSocket-Accept: " + NewKey);
this.WriteLine("Sec-WebSocket-Protocol: lorem.ipsum.com");
this.WriteLine("\r\n");
}
そして、(この時点で)クライアントからの次の出力が得られます。
#WebSocket Starting
#WebSocket Instantiated
#WebSocket Events Attached
#WebSocket Connection Established
#WebSocket BinaryType: blob
#WebSocket Protocol: lorem.ipsum.com
#WebSocket Extensions:
#WebSocket Output Written to Server: TestOutput
この時点で、私は以下のサーバー側のメソッドを実行しようとした場合、クライアントはそのように切断:
#WebSocket Connection Aborted:
Reason: 1006
Reason:
Clean: false
メッセージコード: -Taken私はネットで見つけ、何かからは、少し修正...
public void WriteMessage(byte[] Payload)
{
byte[] Message;
int Length = Payload.Length;
int MaskLength = 4;
if (Length < 126)
{
Message = new byte[2 + MaskLength + Length];
Message[1] = (byte)Length;
}
else if (Length < 65536)
{
Message = new byte[4 + MaskLength + Length];
Message[1] = (byte)126;
Message[2] = (byte)(Length/256);
Message[3] = (byte)(Length % 256);
}
else
{
Message = new byte[10 + MaskLength + Length];
Message[1] = (byte)127;
int left = Length;
int unit = 256;
for (int i = 9; i > 1; i--)
{
Message[i] = (byte)(left % unit);
left = left/unit;
if (left == 0)
break;
}
}
//Set FIN
Message[0] = (byte)129;// (0 | 0x80);
//Set mask bit
//Message[1] = (byte)(Message[1] | 0x80);
//GenerateMask(Message, Message.Length - MaskLength - Length);
//if (Length > 0)
//MaskData(Payload, 0, Length, Message, Message.Length - Length, Message, Message.Length - MaskLength - Length);
char[] output = new char[Message.Length-4];
for(int i = 0, y = 0, z = 0; i < Message.Length; i++)
{
if (Message[z] == '\0')
{
if (Payload.Length > i-z)
output[i] = (char)Payload[y++];
}
else
{
output[i] = (char)Message[z++];
}
}
this.OutputWriter.Write(output, 0, output.Length);
this.OutputWriter.Flush();
}
更新日: この文書のすべてのコードを最新のものに置き換えました。
要約すると:
- The client-server handshake has been matched on both sides.
- A path has been defined in the URI for the WebSocket.
- Data packets are now being 'properly' framed.
これを編集しているときに、私が唯一気づいた一つのポイントは、私のWriteMessageメソッドの最後の数行です。すべてのフレーミングを行った後、私はバイト配列を文字配列に変換し、それを送るためにStreamReader.Writeを使います。私はこれが実行可能な解決策であるかどうかわからないので、そうでない場合は私にチェックを入れてください。
そうでなければ、私はうんざりです。これは、私が何かを読んだ基準のすべてに従っているようだが、それでも私は悲惨に失敗する。私はそれが働くことができるなら、これはかなりの取引メーカーです。だから誰の助けにも本当に感謝しています。
ありがとうございます。 -DigitalJedi facepalm
あなたはクライアントとサーバーサイドを書きましたか?あなたはコードを提供することができますか、あなたが実行するハンドシェークの種類とあなたはそれをどのようにしますか? – Kerwindena
絶対に - 私は今すぐ編集します。 – DigitalJedi805
洗練されたものがあれば教えてください。 – DigitalJedi805