UPDATE3: 我与开发人员联系过。他说这是一个错误,现在他正试图修复它。所以我认为这个问题得到了回答。 (该错误出现在3.4版本中)
UPDATE3 END
UPDATE2: 它只会用很长的字符串冻结。现在两个版本都在代码中。
UPDATE2 END
更新 我查找了可用的替代方法(此处:WebSocket server implementations for Delphi)并开始测试ics-websockets(https://github.com/fajar-khairil/ics-websockets)。 我在通过wlan连接到服务器的移动设备上启动了websocket。如果我超出范围,服务器将继续发送数据而不冻结,然后在某些时候关闭连接。在我看来,这是应该的方式.. 我想我会尝试联系esegece的人。也许他们知道我做错了什么.. 更新结束
我在Delphi XE5中使用sgcWebSocketServer(最新版本3.4主页:http://websockets.esegece.com/)。 客户端使用嵌入在html文件中的javascript websocket。
如果我连接无线客户端并重复从服务器向客户端发送消息,如果客户端断开连接,服务器将冻结10-30秒。它看起来像是一个基本的超时问题,但只有无线客户端会冻结服务器。
为什么会这样?我不认为我应该在通过websocket发送数据之前检查每个客户端的连接。 (我也不知道如何)
据我所知,只有一种方法可以写入数据(WriteData),那我该怎么办?我该如何防止这种冻结? sgcWebSocketServer组件是多线程的,至少文档是这样说的。所以我不认为将WriteData放在一个线程中将是一个很好的解决方案。
这是我的HTML代码:
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
var wsUri = "ws://192.168.xxx.yyy:12345";
var output;
function init()
{
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket()
{
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt)
{
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onClose(evt)
{
writeToScreen("DISCONNECTED");
}
function onMessage(evt)
{
writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
}
function onError(evt)
{
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message)
{
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message)
{
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
这是我在德尔福的主要部门:
unit U_Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, sgcWebSocket_Classes,
sgcWebSocket_Server, sgcWebSocket, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
WebSocketServer: TsgcWebSocketServer;
Timer1: TTimer;
Memo1: TMemo;
procedure WebSocketServerConnect(Connection: TsgcWSConnection);
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
sGUID : String;
implementation
{$R *.dfm}
procedure TForm1.Timer1Timer(Sender: TObject);
var
bErgebnis: boolean;
sData : String;
begin
// Works
bErgebnis := WebSocketServer.WriteData(sGUID,'DATA');
// Will freeze
sData := 'DATA!';
for i := 0 to 100 do
begin
sData := sData + 'DATA!';
end;
bErgebnis := WebSocketServer.WriteData(sGUID,sData);
Memo1.Lines.Add(TimeToStr(now()) + (bErgebnis.ToString()));
end;
procedure TForm1.WebSocketServerConnect(Connection: TsgcWSConnection);
begin
sGUID := Connection.Guid;
Timer1.Enabled := True;
end;
end.
一旦客户端连接,我将guid保存在sGUID中并激活计时器。计时器每隔500ms触发一次TForm1.Timer1Timer程序。
如果&#34; ThreadPool&#34; WebSocketServer上的选项是否有效..问题仍然存在。
在我的例子中,我使用了TsgcWebSocketServer和计时器的可视组件。如果它可以帮助我重写测试,那么它们将直接在源代码中创建。
答案 0 :(得分:0)
这是版本3.4中的错误,因此您只需要等待修复。