为什么如果无线客户端失去连接,sgcWebSocketServer 会冻结



>UPDATE3:我与开发人员取得了联系。他说这是一个错误,现在他正试图修复它。所以我认为这个问题得到了回答。(该错误存在于版本 3.4 中(

UPDATE3完

UPDATE2:它只会用很长的字符串冻结。现在两个版本都在代码中。

UPDATE2结束

更新:我查找了可用的替代方案(这里:Delphi的WebSocket服务器实现(,并开始测试ics-websockets(https://github.com/fajar-khairil/ics-websockets(。我在通过 wlan 连接到服务器的移动设备上启动了 websocket。如果我超出范围,服务器将继续发送数据而不会冻结,然后在某个时候关闭连接。在我看来,这就是它应该的方式。我想我会尝试联系来自埃塞盖斯的人。也许他们知道我做错了什么。更新结束

我在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 中并激活计时器。计时器每 500 毫秒触发一次 TForm1.Timer1Timer 过程。

WebSocketServer 上的"ThreadPool"选项是否处于活动状态并不重要......问题仍然存在。

在我的示例中,我使用了 TsgcWebSocketServer 和计时器的可视组件。如果有帮助,我可以重写测试,以便直接在源代码中创建它们。

这是 3.4 版中的一个错误,因此您只需要等待修复。

相关内容

  • 没有找到相关文章