我正在经历“似乎”是一个独特的问题。我现在有一个客户端/服务器模型,它从 Windows 表单获取输入并将其推送到我从头开始编写的服务器,从那里,它应该通过 websocket 被拉到网页。
我刚刚克服了握手并有效地建立了联系;但是,我的 onMessage 方法似乎从未受到打击(无论我向它发送文本的时间有多快/多晚),而且它似乎在理论上会触发时,会发生其他事情......
当我从向服务器发送输入的客户端发送文本时,它会传递第一行并等待第二行。服务器接收此输入并将其写入所有连接的“输出”客户端。这意味着包括我的 websocket。这是我迷路的地方。第一行被“写入”(根据服务器),但“onmessage”事件从未发生。如果我向服务器发送第二行,在尝试写入时,服务器会抛出异常,范围为“无法将数据写入传输连接:已建立的连接被主机中的软件中止”。并且客户端触发onclose。
也许有人可以提供一些见解。这是我的 websocket 代码:
<!DOCTYPE html>
<meta charset="utf-8" />
<html>
<head>
<script language="javascript" type="text/javascript">
var wsUri = "ws://localhost:9001";
var output;
function init()
{
writeToScreen("Starting");
testWebSocket();
}
function testWebSocket()
{
websocket = new WebSocket(wsUri);
websocket.async = false;
writeToScreen("Instantiated");
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
writeToScreen("Evented");
//onOpen(null);
}
function onOpen(evt)
{
try
{
writeToScreen("CONNECTED");
}
catch( e )
{
writeToScreen(e);
}
}
function onClose(evt)
{
writeToScreen("DISCONNECTED");
}
function onMessage(evt)
{
try
{
writeToScreen("Message");
writeToScreen("<span style=\"color: blue;\">RESPONSE: " + evt.data+"</span>");
}
catch( e )
{
writeToScreen(e);
}
}
function onError(evt)
{
writeToScreen("<span style=\"color: red;\">ERROR:</span> " + evt.data);
}
function doSend(message)
{
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message)
{
output = document.getElementById("output");
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
</head>
<body>
<div id="output">
</div>
</body>
</html>
及其对应的输出:
Starting
Instantiated
Evented
CONNECTED
DISCONNECTED
这是服务器“写入”方法(来自我编写并继承自的类):
public virtual void WriteLine(String Argument)
{
if (this.ClientStream == null)
{
try
{
this.ClientStream = new NetworkStream(this.ClientSocket);
this.WriteLine(Argument);
return;
}
catch (Exception e)
{
throw new Exception("Exception encountered while writting to Client.\n" + e.Message);
}
}
else if (this.OutputWriter == null)
{
try
{
this.OutputWriter = new StreamWriter(this.ClientStream);
this.WriteLine(Argument);
return;
}
catch (Exception e)
{
throw new Exception("Exception encountered while writting to Client.\n" + e.Message);
}
}
else
{
try
{
this.OutputWriter.Write(Argument + "\r\n");
this.OutputWriter.Flush();
return;
}
catch (Exception e)
{
throw new Exception("Exception encountered while writting to Client.\n" + e.Message);
}
}
}
和服务器“连接”方法(来自我继承的类):
public void Start()
{
if (this.Server == null)
{
throw new Exception("Could not start TelnetServer.Listener, Server is null.");
}
else if (this.RunningThread == null)
{
this.RunningThread = new Thread(this.Start);
this.RunningThread.Name = "TelnetServer.Listener:" + this.Port;
this.RunningThread.Start();
return;
}
else if (this.LocalAddress == null)
{
this.LocalAddress = IPAddress.Any;
this.Start();
return;
}
else if (this.NetworkListener == null)
{
this.NetworkListener = new TcpListener(this.LocalAddress, this.Port);
this.NetworkListener.Start();
this.Start();
return;
}
else
{
this.RunningFlag = true;
while (this.IsRunning())
{
try
{
Socket NewSocket = this.NetworkListener.AcceptSocket();
this.Server.Connect(NewSocket);
continue;
}
catch (Exception e)
{
this.Print("Exception encountered while creating new Client.");
this.Print(e.Message);
continue;
}
}
}
}
如果需要更多信息,我很乐意详细说明。请注意,当我获得新连接时,我在“最终”类中进行了完整的握手,最终类中的“写入”方法将消息发送到上述写入方法。
再次提前感谢。
[编辑] 添加发送帧;现在它在第一条消息上失败了。if (HeaderFinished && HeaderSent) base.WriteLine("\u0000" + Encoding.UTF8.GetBytes(Argument) + "\uffff"); 否则 base.WriteLine(Argument); [/编辑]