sgcWebSockets 五分钟上手
您已经安装了库,组件面板也已显示。本页将带您从这里出发,搭建一个接受连接的服务器,以及一个发送消息并读取回复的客户端。下面的所有内容都来自下载包中自带的演示项目,因此您可以直接打开项目,而不必手动输入。
您已经安装了库,组件面板也已显示。本页将带您从这里出发,搭建一个接受连接的服务器,以及一个发送消息并读取回复的客户端。下面的所有内容都来自下载包中自带的演示项目,因此您可以直接打开项目,而不必手动输入。
两个非可视组件,uses 子句中的一个单元,以及事件处理程序参数类型所需的另一个单元。
TsgcWebSocketClient,声明在 sgcWebSocket.pas 中,注册在 SGC WebSockets 组件面板页上。先设置 Host 和 Port,再设置 Active。
TsgcWebSocketServer,位于同一个单元和同一个组件面板页。先设置 Port,再设置 Active。它负责监听、升级握手并触发 OnConnect。
每个事件都会传给您一个 TsgcWSConnection,它位于 sgcWebSocket_Classes.pas 中。演示项目中写的是 uses sgcWebSocket, sgcWebSocket_Classes;,您也应该这样写。
这两个单元都没有平台保护,两个组件也都使用 ComponentPlatforms(0) 注册,因此 VCL、FMX、控制台和服务目标都可以编译。安装包中还附带一个 FireMonkey 客户端演示。
版本列给出的是实际控制代码的定义,以及它在 Source/sgcVer.inc 中所在的行号。
| 项目 | 值 |
|---|---|
| IDE | Delphi 7 到 RAD Studio 13,以及 C++Builder 2007 到 13。每个 IDE 版本在 Packages\ 下都有一个包组。 |
| uses 子句 | 组件使用 sgcWebSocket,TsgcWSConnection 使用 sgcWebSocket_Classes。 |
| 客户端版本 | TsgcWebSocketClient 被包裹在 {$IFDEF SGC_WS_CLIENT} 中。SGC_WS_CLIENT 定义在第 697 行,位于从第 675 行延伸到第 724 行的 {$IFDEF SGC_EDT_STD} 块内。因此是 Standard 及以上版本。 |
| 服务器版本 | TsgcWebSocketServer 直接包裹在 {$IFDEF SGC_EDT_PRO} 中,它在 sgcWebSocket_Reg.pas 中的组件面板注册也在同一个保护块内。Professional 功能块从第 727 行延伸到第 758 行。因此是 Professional 及以上版本。Standard 许可证提供客户端,不提供服务器。 |
| 组件面板页 | 在 {$IFDEF SGC_PACK_WEBSOCKETS} 下注册,该符号定义在第 852 行。 |
| 平台 | sgcWebSocket.pas、sgcWebSocket_Client.pas 和 sgcWebSocket_Server.pas 中没有单元级平台保护。Windows 只是有条件地引入 Windows 单元,别无其他。 |
不确定您使用的是哪个版本?打开 Source/sgcVer.inc,查看前五行。其中的 SGC_EDT_* 定义是累加的,因此 All-Access 会定义全部,而 Standard 只定义前两个。
从压缩包到可放置的组件共五步。请先编译运行时包,再安装设计时包,因为后者引用前者。
将下载文件解压到您选择的文件夹。本页其余部分称该文件夹为 {$DIR}。Source\、Packages\、Demos\ 和 lib*\ 文件夹都在其下。
依次选择 Tools、Options、Library。添加 {$DIR}\source 以及与您的 IDE 对应的文件夹,例如 RAD Studio 13 使用 {$DIR}\libD13\$(Platform),12 使用 {$DIR}\libD12\$(Platform)。
针对您的 IDE 版本,打开 {$DIR}\Packages\sgcWebSocketsD13.groupproj。先编译 sgcWebSocketsD13.dpk,再安装 dclsgcWebSocketsD13.dpk。C++Builder 使用同一文件夹中的 .cbproj 文件。
会出现一个名为 SGC WebSockets 的新页面。在 Standard 构建中,它包含 TsgcWebSocketClient。在 Professional 及以上版本中,还包含 TsgcWebSocketServer、TsgcWebSocketHTTPServer、TsgcWebSocketProxyServer 和 TsgcWebSocketLoadBalancerServer。
在编写任何代码之前,先打开 {$DIR}\Demos\01.WebSocket_Quick_Start\01.Server_and_Client_Chat。它是库中最小的可运行配对,下面的代码就来自它。
启动服务器,启动客户端,发送一个字符串。服务器选项卡在一个端口上监听;客户端选项卡连接到该端口并写入一条消息。
uses
Classes, SysUtils,
// sgc
sgcWebSocket, sgcWebSocket_Classes;
procedure TfrmServerChat.btnStartClick(Sender: TObject);
begin
WSServer.Port := 5418;
WSServer.Active := True;
memoLog.Lines.Add('#started');
end;
procedure TfrmServerChat.WSServerConnect(Connection: TsgcWSConnection);
begin
memoLog.Lines.Add('Connected: ' + Connection.IP);
end;
procedure TfrmServerChat.WSServerDisconnect(Connection: TsgcWSConnection;
Code: Integer);
begin
memoLog.Lines.Add('Disconnected (' + IntToStr(Code) + '): ' + Connection.IP);
end;
procedure TfrmServerChat.WSServerMessage(Connection: TsgcWSConnection;
const Text: string);
begin
memoLog.Lines.Add(Text);
// send it straight back, so the client has something to read
Connection.WriteData('echo: ' + Text);
end;
将 TsgcWebSocketServer 放到窗体上,命名为 WSServer,然后让 IDE 通过对象检查器生成这四个处理程序。Connection.IP 和 Connection.WriteData 都来自 TsgcWSConnection,这就是 sgcWebSocket_Classes 要出现在 uses 子句中的原因。
uses
Classes, SysUtils,
// sgc
sgcWebSocket, sgcWebSocket_Classes;
procedure TfrmClientChat.btnStartClick(Sender: TObject);
begin
WSClient.Host := 'localhost';
WSClient.Port := 5418;
WSClient.TLS := False;
WSClient.Active := True;
end;
procedure TfrmClientChat.btnSendClick(Sender: TObject);
begin
if WSClient.Active then
WSClient.WriteData('Hello from Delphi')
else
raise Exception.Create('Not connected');
end;
procedure TfrmClientChat.WSClientConnect(Connection: TsgcWSConnection);
begin
memoLog.Lines.Add('#connected');
end;
procedure TfrmClientChat.WSClientMessage(Connection: TsgcWSConnection;
const Text: string);
begin
memoLog.Lines.Add(Text);
end;
先运行服务器项目,再运行这个项目。客户端日志中会出现 #connected,并且 echo: Hello from Delphi 会通过 OnMessage 返回。这个往返过程就是整个快速入门。
program WSConsoleClient;
{$APPTYPE CONSOLE}
uses
Classes, SysUtils,
// sgc
sgcWebSocket, sgcWebSocket_Classes;
type
TChatHandler = class
procedure DoConnect(Connection: TsgcWSConnection);
procedure DoMessage(Connection: TsgcWSConnection; const Text: string);
end;
procedure TChatHandler.DoConnect(Connection: TsgcWSConnection);
begin
Writeln('#connected');
end;
procedure TChatHandler.DoMessage(Connection: TsgcWSConnection;
const Text: string);
begin
Writeln('Server says: ', Text);
end;
var
oClient: TsgcWebSocketClient;
oHandler: TChatHandler;
begin
oHandler := TChatHandler.Create;
oClient := TsgcWebSocketClient.Create(nil);
try
oClient.Host := 'localhost';
oClient.Port := 5418;
oClient.WatchDog.Enabled := True; // reconnect on its own
// assign the handlers BEFORE Active, or the first
// OnConnect can fire with nothing attached
oClient.OnConnect := oHandler.DoConnect;
oClient.OnMessage := oHandler.DoMessage;
oClient.Active := True;
oClient.WriteData('Hello from Delphi');
Readln;
finally
oClient.Free;
oHandler.Free;
end;
end.
客户端运行在自己的线程中,因此控制台程序必须保持主线程存活。这正是 Readln 的作用。
服务器和客户端选项卡取自随包附带的演示 Demos\01.WebSocket_Quick_Start\01.Server_and_Client_Chat,并去掉了演示中复选框和编辑框相关的代码。第三个选项卡使用相同的调用,但针对的是在运行时创建的组件,而不是放在窗体上的组件。
四个事件能说明首次运行的全部情况,在继续之前,您需要把这四个事件都连接好。
Active在服务器上,Active := True 要么成功,要么抛出异常。如果端口已被占用,您会在这里发现,而不是三步之后。
OnConnectprocedure(Connection: TsgcWSConnection)。两端都会触发。在服务器上,Connection.IP 会告诉您是谁连接了进来;在客户端上,它证明握手已经升级。
OnMessageprocedure(Connection: TsgcWSConnection; const Text: string)。客户端收到返回的回显,就证明了端到端的往返流程。
OnError 和 OnExceptionprocedure(Connection: TsgcWSConnection; const Error: string) 和 procedure(Connection: TsgcWSConnection; E: Exception)。两者都要连接。没有它们,故障会悄无声息,看起来就像什么都没发生。
几乎所有首次运行的问题都是下面这六种之一。
TsgcWebSocketServer服务器类只有在定义了 SGC_EDT_PRO 时才会编译(位于 sgcWebSocket.pas 第 130 行),并且只在同一个保护块内注册。在 Standard 构建中,有客户端而没有服务器。这是许可证的限制,而不是安装损坏。
TsgcWSConnection组件位于 sgcWebSocket,连接对象位于 sgcWebSocket_Classes。请把第二个单元添加到 uses 子句中。所有随包附带的演示都同时包含这两个单元。
设置 WatchDog.Enabled := True,让断开的连接自动重连,并处理 OnError 和 OnException。没有处理程序的静默断开看起来就像什么都没发生。
写入之前,先确认客户端确实已经连通。在未激活的客户端上调用 WriteData 没有任何作用,这就是演示在发送之前先检查 if WSClient.Active then 的原因。
服务器的另一个实例或其他程序仍然占用着该端口。请停止它,或者将服务器改到空闲端口。演示的默认端口是 5416 和 5418。
wss:// 连接需要可用的 TLS 后端。通过 TLSOptions.IOHandler 选择一个:OpenSSL 适用于所有平台,SChannel 适用于 Windows 且无需部署 DLL,或者使用 Enterprise 版中的 Apple 和 Android 原生处理程序。
聊天配对只是起点。下面是工作通常会延伸的四个方向,而且这四个方向都在同一个库中。
同一个客户端可以承载 MQTT、AMQP、STOMP、Kafka 和 WAMP 子协议组件。放置其中一个,将它的 Client 属性指向您的 TsgcWebSocketClient,就可以连接到代理了。
TsgcWebSocketHTTPServer 在同一个端口上响应普通 HTTP 请求和 WebSocket 升级,当浏览器需要先获取页面再打开套接字时,这正是您想要的。
参考页面记录了每个属性和事件。演示项目就在您的下载包内,位于 Demos\01.WebSocket_Quick_Start 下。
参考:WebSocket 客户端
TsgcWebSocketClient 上的每个属性、方法和事件。
|
打开 | |
参考:WebSocket 服务器
TsgcWebSocketServer 上的绑定、身份验证、广播和连接管理。
|
打开 | |
| 在线帮助:TsgcWebSocketClient 自动生成的组件参考,始终与当前版本保持同步。 | 打开 | |
| 我需要哪个版本 逐项说明 Standard、Professional、Enterprise 和 All-Access 各自启用的功能。 | 打开 | |
| 下载试用版 与正式版相同的安装程序,有时间限制,每个 IDE 版本一个。 | 打开 | |
| 用户手册(PDF) 涵盖库中每个组件的完整手册。 | 打开 |
相关阅读:WebSocket 到底是什么、客户端连接和 WatchDog 事件,以及保护 WebSocket 服务器。每个产品都有自己的快速入门,列在入门页面上。
sgcWebSocket 提供 TsgcWebSocketClient 和 TsgcWebSocketServer。还要添加 sgcWebSocket_Classes,因为每个事件都会传给您一个 TsgcWSConnection,而该类型就声明在那里。随包附带的演示写的是 uses sgcWebSocket, sgcWebSocket_Classes;,服务器演示还额外添加了 sgcWebSocket_Server。
{$IFDEF SGC_EDT_PRO} 内编译,它在 sgcWebSocket_Reg.pas 中的组件面板注册也位于同一个保护块内。SGC_EDT_PRO 会开启 Professional 功能块,即 sgcVer.inc 的第 727 行到第 758 行。Standard 构建只编译客户端。客户端定义 SGC_WS_CLIENT 位于第 697 行,在 Standard 块(第 675 行到第 724 行)之内。
sgcWebSocket_Classes.pas。OnConnect 是 procedure(Connection: TsgcWSConnection)。OnDisconnect 是 procedure(Connection: TsgcWSConnection; Code: Integer)。OnMessage 是 procedure(Connection: TsgcWSConnection; const Text: string)。OnError 是 procedure(Connection: TsgcWSConnection; const Error: string)。OnException 是 procedure(Connection: TsgcWSConnection; E: Exception)。请让 IDE 生成它们,而不要手动输入,因为多一个或少一个参数是第一个项目中最常见的编译错误。
sgcWebSocket.pas、sgcWebSocket_Client.pas 和 sgcWebSocket_Server.pas 没有单元级平台保护,两个组件也都使用 ComponentPlatforms(0) 注册,因此 IDE 不会把它们限制在某个目标平台上。FireMonkey 客户端和服务器演示位于 Demos\01.WebSocket_Quick_Start\07.Firemonkey_Server_and_Client。库中唯一有平台限制的 WebSocket 组件是 TsgcWebSocketClient_WinHTTP,仅支持 Win32 和 Win64。
TLS := True,并将 Port 指向 TLS 端口。然后通过 TLSOptions.IOHandler 选择 TLS 后端。OpenSSL 适用于所有平台,在 Windows 上需要把 libcrypto-3.dll 和 libssl-3.dll 放在可执行文件旁边。SChannel 仅适用于 Windows,无需额外文件。Apple 和 Android 原生处理程序是 Enterprise 功能。
Active := True 之前分配事件处理程序,否则第一个 OnConnect 可能在处理程序附加之前就已触发。在控制台应用程序中,请记住客户端运行在自己的线程中,因此主线程必须保持存活,这就是示例以 Readln 结尾的原因。
WatchDog.Enabled := True,如果默认值过于频繁,可再调整 WatchDog.Interval 和 WatchDog.Attempts。
Demos\ 下。本页使用的配对是 01.WebSocket_Quick_Start\01.Server_and_Client_Chat。同样值得尽早打开的有:06.Authentication(检查凭据的服务器)、07.Firemonkey_Server_and_Client(跨平台客户端)和 12.Groups(向一部分连接广播)。