TsgcWebSocketHTTPServer
TsgcWebSocketHTTPServer实现了服务器WebSocket组件,可以像TsgcWebSSocketServer一样处理多线程客户端连接,并允许使用内置的HTTP服务器为HTML页面提供服务,为WebSocket连接和HTTP请求共享同一端口。
按照以下步骤配置此组件:
1:从选项卡上拖入TsgcWebSocketHTTPServer到FROM上
2:设置端口(默认值为80)。如果您位于防火墙后面,则可能需要对其进行配置。
3:设置允许的规格,默认情况下允许所有规格。
-RFC6455:是标准和推荐的WebSocket规范。
-Hixie76:这是一个草稿,如果你想支持Safari 4.2这样的旧浏览器,只建议建立Hixie76连接
4:如果需要,可以处理事件:
-OnConnect:每次建立WebSocket连接时,都会触发此事件。
-OnDisconnect:每次断开WebSocket连接时,都会触发此事件。
-OnError:每次出现WebSocket错误(如错误的握手)时,都会触发此事件。
-OnMessage:每当客户端发送文本消息并被服务器接收时,就会触发此事件。
-OnBinary:每当客户端发送二进制消息并被服务器接收时,就会触发此事件。
-OnHandhake:在服务器端评估握手后触发此事件。
-OnCommandGet:当HTTP服务器接收到请求HTML页面、图像的GET、POST或HEAD命令时,将触发此事件…示例:
AResponseInfo.ContentText := '<HTML><HEADER>TEST</HEAD><BODY>Hello!</BODY></HTML>';
-OnCommandOther:当HTTP服务器接收到不同于GET、POST或HEAD的命令时,将触发此事件。
-OnCreateSession:当HTTP服务器创建新会话时激发此事件。
-OnInvalidSession:当HTTP请求使用无效/过期会话时,将触发此事件。
-OnSessionStart:当HTTP服务器启动新会话时触发此事件。
-OnCommandOther:当HTTP服务器关闭会话时触发此事件。
-OnException:当HTTP服务器抛出异常时,将触发此事件。
-OnAuthentication:如果启用了身份验证,则触发此事件。您可以检查客户端传递的用户和密码,并启用/禁用Authenticated Variable。
-OnUnknownProtocol:如果未检测到WebSocket协议(例如,因为客户端使用的是普通TCP协议),在这种情况下,可以接受或拒绝连接。
-OnBeforeHeartBeat:如果启用了HeartBeat,则允许将自定义HeartBeat设置Handled参数设置为True(这意味着不会发送标准的websocket ping)。
-OnBeforeForwardHTTP:允许将HTTP请求转发到另一个HTTP服务器。使用forward属性启用此功能并设置目标URL。
-OnHTTPUploadBeforeSaveFile:当一个新文件上传并保存到磁盘文件之前,该事件被触发,允许修改将保存的文件名。
-OnHTTPUploadAfterSaveFile:在上载新文件并将其保存到磁盘文件后,将触发该事件。
-OnHTTPUploadReadInput:当表单post读取与文件不同的输入变量时,将触发事件。
*在某些情况下,由于未经请求的连接,您可能会消耗大量的cpu,在这些情况下,如果是HTTP请求或未知协议请求的关闭连接,只需返回错误500。
5.创建一个过程并设置属性Active=true。
最常见的用途
1>HTTP Server Requests(HTTP服务器请求)
使用OnCommandGet处理HTTP客户端请求。使用以下参数:
RequestInfo: 包含HTTP请求信息。
ResponseInfo: 是HTTP请求的HTTP响应。
ContentText: 是文本格式的响应。
ContentType: 内容类型。
ResponseNo: HTTP响应数,例如:200。
procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); begin if ARequestInfo.Document = '/' then begin AResponseInfo.ContentText := '<html><head><title>Test Page</title></head><body></body></html>'; AResponseInfo.ContentType := 'text/html'; AResponseInfo.ResponseNo := 200; end; end;
2>HTTP Dispatch Files(HTTP调度文件)
当客户端请求文件时,OnCommandGet事件被激发,但您可以使用DocumentRoot属性自动分派文件。
示例:如果将DocumentRoot设置为c:\www\files。每次请求新文件时,将在此文件夹中搜索文件是否存在,如果存在,将自动发送。
3>-5>HTTP2相关 略
6>Post Big Files(大文件上传)
相关组件:
TsgcWebSocketHTTPServer
TsgcWebSocketServer_HTTPAPI
当HTTP客户端发送多部分/表单数据流时,服务器会将该数据流保存在内存中。当文件很大时,服务器可能会出现内存不足的异常,为了避免这些异常,服务器有一个名为HTTPUploadFiles的属性,您可以在其中配置POST流的处理方式:在内存中或作为文件流。如果流被处理为文件流,则接收的流直接存储在硬盘中,从而避免了内存问题。
要将服务器配置为将多部分/表单数据流保存为文件流,请执行以下步骤:
1:设置属性HTTPUploadFiles.StreamType = pstFileStream。使用此设置,服务器将在硬盘中存储这些流。
2:您可以配置文件作为文件流存储的最小字节大小。默认情况下,该值为零,这意味着所有流都将存储为文件流。
3:使用SaveDirectory存储流的文件夹(如果未设置)将存储在应用程序所在的同一文件夹中。
4:当客户端发送多部分/表单数据时,内容在边界内编码,如果启用了RemoveBoundaries属性,则在接收到完整流后,将自动提取边界的内容。
示例代码:
首先创建一个新的服务器实例,并将Streams保存为File Streams。
oServer := TsgcWebSocketHTTPServer.Create(nil); oServer.Port := 5555; oServer.HTTPUploadFiles.StreamType := pstFileStream; oServer.Active := True;
然后使用以下配置创建一个新的html文件
<html> <head><title>sgcWebSockets - Upload Big File</title></head> <body> <form action="http://127.0.0.1:5555/file" method="post" enctype="multipart/form-data" accept-charset="UTF-8"> <input type="file" name="file_1" /> <input type="submit" /> </form> </body> </html>
最后,用web浏览器打开html文件并将文件发送到服务器。服务器将创建一个扩展名为“.sgc_ps”的新文件流,当流被完全接收到时,它将从边界提取文件。
事件
有2个事件可用于自定义上载文件流(需要启用属性HTTPploadFiles.RemoveBoundaries)
OnHTTPUploadBeforeSaveFile
此事件在保存文件之前激发,并允许自定义接收的文件的名称。
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; var aFileName: string; var aFilePath: string); begin if aFileName = "test.jpg" then aFileName := "custom_test.jpg"; end;
OnHTTPUploadAfterSaveFile
保存文件后激发此事件,并允许知道保存的文件的名称。
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; const aFileName: string; const aFilePath: string); begin DoLog("File Received: " + aFileName); end;
OnHTTPUploadReadInput
当解码器读取与文件输入不同的输入值时(例如:如果表单具有一些变量,如名称、日期…),就会触发此事件。
procedure OnHTTPUploadReadInputEvent(Sender: TObject; const aName: string; const aValue: string); begin DoLog("Input value received: " + aName + ":" + aValue); end;
7>HTTP 404 Error without Response Body(没有响应正文的HTTP 404错误)
默认情况下,如果没有分配ContentText或ContentStream,Indy库会在HTTP响应中添加一些内容体。如果由于404错误或类似错误,您希望返回空的响应体,可以使用以下技巧。
创建一个没有内容的新TStringStream,并将其分配给HTTP响应的ContentStream属性,这样,HTTP响应将在默认情况下不使用HTML标记的情况下发送。
procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); begin AResponseInfo.ContentStream := TStringStream.Create(''); AResponseInfo.ContentType := 'text/html'; AResponseInfo.ResponseNo := 404; end;
8>HTTP Server Sessions(HTTP服务器会话)
HTTP是无状态协议(至少在HTTP1.1之前),所以客户端请求一个文件,服务器向客户端发送响应,连接被关闭(好吧,您可以启用keep-alive,然后连接不会立即关闭,但这远远超出了本文的目的)。会话的使用允许存储有关客户端的一些信息,例如,这可以在客户端登录期间使用。您可以使用任何会话唯一ID,在会话列表中搜索(如果已存在),如果不存在,则创建新会话。会话可以在一段时间后销毁,而不使用它,也可以在客户端注销后手动销毁。
配置
TsgcWebSocketHTTPServer中有一些属性可以启用/禁用服务器组件中的会话。让我们看看最重要的:
SessionState:这是必须启用才能使用会话的第一个属性。如果未启用此属性,会话将无法工作.
SessionTimeout:在这里,您必须设置一个大于零(以毫秒为单位)的值,以便会话处于活动状态的最长时间。
AutoStartSession:可以自动(AutoStartSession=true)或手动(AutoStartSession=false)创建会话。若会话是自动创建的,服务器将使用RemoteIP作为唯一标识符,以查看是否存储了活动会话。
TsgcWebSocketHTTPServer1.SessionState := True; TsgcWebSocketHTTPServer1.SessionTimeout := 600000; AutoStartSession := False;
创建会话
为了创建一个新的会话,我们必须创建一个唯一的新会话id,您可以使用任何方法,例如:如果客户端正在进行身份验证,则可以使用用户+密码+远程ip作为会话id。
然后,我们在会话列表中搜索,如果已经存在,如果不存在,我们创建一个新的会话列表。
创建新会话时,调用OnSessionStart事件,会话关闭时,引发OnSessionEnd事件。
procedure OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); var vID: String; oSession: TIdHTTPSession; begin if ARequestInfo.Document = '/' then AResponseInfo.ServeFile(AContext, 'yourpathhere\index.html') else begin // check if user is valid if not ((ARequestInfo.AuthUsername = 'user') and (ARequestInfo.AuthPassword = 'pass')) then AResponseInfo.AuthRealm := 'Authenticate' else begin // create a new session id with authentication data vID := ARequestInfo.AuthUsername + '_' + ARequestInfo.AuthPassword + '_' + ARequestInfo.RemoteIP; // search session oSession := TsgcWebSocketHTTPServer1.SessionList.GetSession(vID, ARequestInfo.RemoteIP); // create new session if not exists if not Assigned(oSession) then oSession := TsgcWebSocketHTTPServer1.SessionList.CreateSession(ARequestInfo.RemoteIP, vID); AResponseInfo.ContentText := '<html><head></head><body>Authenticated</body></html>'; AResponseInfo.ResponseNo := 200; end; end; end;
方法
Broadcast:向所有连接的客户端发送消息。
Message / Stream:要发送到所有客户端的消息或流。
Channel:如果指定频道,则消息将仅发送给订户。
Protocol:如果已定义,则消息将仅发送到特定协议。
Exclude:如果已定义,则排除连接guid的列表(用逗号分隔)。
Include:如果已定义,则包含连接guid列表(用逗号分隔)。
WriteData:向单个或多个客户端发送消息。每当客户端建立WebSocket连接时,此连接都由Guid标识,您可以使用此Guid向客户端发送消息。
Ping:向所有连接的客户端发送ping。
DisconnectAll:断开所有活动连接。
属性:
Connections:包含所有客户端连接的列表。
Bindings:用于管理IP和端口。
DocumentRoot:在这里,您可以定义一个目录,在该目录中可以放置所有html文件(javascript、html、CSS…)。如果客户端发送请求,服务器将自动在该目录上搜索该文件,如果找到,将提供服务。
Extensions:您可以对发送的消息启用压缩(如果客户端不支持压缩,消息将自动交换而不进行压缩)。
MaxConnections:允许的最大连接数(如果为零,则没有限制)。
Count:连接数计数。
AutoStartSession:如果SessionState处于活动状态,则当服务器收到新的HTTP请求时,将创建一个新会话。
SessionState:如果活动,则启用HTTP会话。
KeepAlive:如果启用,则在发送响应后,连接将保持活动状态。
ReadStartSSL:HTTPS连接尝试启动的最大次数。
SessionList:只读属性,用作为HTTP服务器创建的TIdHTTPSession实例的容器。
SessionTimeOut:会话超时。
HTTP2Options:默认情况下,HTTP/2协议未启用,它使用HTTP1.1处理HTTP请求。如果客户端支持HTTP/2协议,则启用此属性。
-Enabled:如果为true,则支持HTTP/2协议。如果客户端不支持HTTP/2,则HTTP 1.1将用作回退。
-Settings:指定要发送到HTTP/2服务器的标头值。
--EnablePush:默认情况下,此设置可用于避免服务器向客户端推送内容。
--HeaderTableSize:允许发送方通知远程端点用于解码标头块的标头压缩表的最大大小(以八位字节为单位)。编码器可以通过使用特定于报头块内的报头压缩格式的信令来选择等于或小于该值的任何大小。初始值为4096个八位字节。
--InitialWindowSize:指示流级流控制的发送方初始窗口大小(以八位字节为单位)。初始值为65535个八位字节。此设置会影响所有流的窗口大小。
--MaxConcurrentStreams:指示发送方将允许的最大并发流数。这个限制是定向的:它适用于发送方允许接收方创建的流的数量。最初,该值没有限制。
--MaxFrameSize:指示发送方愿意接收的最大帧有效负载的大小(以八位字节为单位)。初始值为16384个八位字节。
--MaxHeaderListSize:此建议设置以八位字节为单位通知对等方发送方准备接受的最大标头列表大小。该值基于标头字段的未压缩大小,包括名称和值的长度(以八位字节为单位)加上每个标头字段32个八位字节的开销。
-Events:在这里,您可以配置是否希望在有新的HTTP/2连接时收到通知。
--OnConnect: 如果在存在新的HTTP/2连接时启用,则将调用OnConnect事件(默认情况下禁用)。
--OnDisconnect:如果在新的HTTP/2断开连接时启用,则将调用OnDisconnect事件(默认情况下禁用)。
HTTPUploadFiles:默认情况下,当客户端使用POST流发送文件时,文件将保存在内存中。如果要将这些流直接保存为文件以避免内存问题,请将StreamType设置为pstFileStream,文件将保存在硬盘中。
MinSize:要保存为文件流的流的最小大小(字节)。默认情况下为零,这意味着所有流都将保存为FileStreams(如果StreamType=pstFileStream)。
RemoveBoundaries:使用POST多部分/表单数据上载的文件封装在边界中,如果启用此属性,文件将从边界提取并保存在硬盘中。
SaveDirectory:保存文件的文件夹。如果为空,将保存在应用程序所在的同一文件夹中。
StreamType:默认情况下,将保存流的流的类型。
-pstMemoryStream:作为存储器流。
-pstFileStream:作为文件流。
目录 返回
首页