WebSocket support in kbmMW #1 – Upcoming
8月28日 ,kbmMW作者发布了文章,宣布即将到来的kbmMW新版本,将支持WebSocket!这是一个令人兴奋的消息!这样,我们就可以基于kbmMW,开发支持WebSocket的Web服务器了!
开发一个这样的服务器,将是一件简单的事件,看代码:
constructor TForm6.Create(Owner:TComponent); begin inherited Create(Owner); FServer:=TkbmMWServer.Create(nil); FTransport:=TkbmMWWebSocketServerTransport.Create(nil); FTransport.Server:=FServer; FTransport.OnWebSocketData:=DoOnWebSocketData; FTransport.OnWebSocketOpen:=DoOnWebSocketOpen; FTransport.OnWebSocketClose:=DoOnWebSocketClose; FTransport.OnWebSocketPong:=DoOnWebSocketPong; FServer.AutoRegisterServices; Log.OutputToStrings(mLog.Lines); end;
新版提供了TkbmMWWebSocketServerTransport,直接在服务端建立TkbmMWWebSocketServerTransport,并实现他的四个事件,然后再设置他的一些属性:
procedure TForm6.btnListenClick(Sender: TObject); begin if FServer.Active then begin FServer.Active:=false; btnListen.Caption:='Listen'; end else begin FTransport.Host:='0.0.0.0'; if chbUseSSL.Checked then begin FTransport.UseSSL:=true; FTransport.Port:=443; FTransport.SetSSLCertificateFromFile('.\domain.crt'); FTransport.SetSSLPrivateKeyFromFile('.\domain.key'); end else begin FTransport.UseSSL:=false; FTransport.Port:=80; end; FServer.Active:=true; btnListen.Caption:='Dont listen'; end; end;
四个事件的代码:
procedure TForm6.DoOnWebSocketData(const AConnection:IkbmMWWebSocketConnection; const AData:TValue); var s:string; begin s:=AData.ToString; Log.Info('Got data:'+s); AConnection.BroadcastText(s); end; procedure TForm6.DoOnWebSocketPong(const AConnection:IkbmMWWebSocketConnection; const AData:TValue); begin Log.Info('Got pong from:'+ AConnection.GetPeerAddr+':'+inttostr(AConnection.GetPeerPort)+ ' : '+AData.ToString); end; procedure TForm6.DoOnWebSocketOpen(const AConnection:IkbmMWWebSocketConnection); begin AConnection.TagString:='TAG1'; Log.Info('Opening websocket connection: '+ AConnection.GetPeerAddr+':'+inttostr(AConnection.GetPeerPort)+ ' now tagged as '+AConnection.TagString); end; procedure TForm6.DoOnWebSocketClose(const AConnection:IkbmMWWebSocketConnection; const ACode:word; const AReason:string); begin Log.Info('Closing websocket connection: '+ AConnection.GetPeerAddr+':'+inttostr(AConnection.GetPeerPort)+ ' Code:'+inttostr(ACode)+' Reason:'+AReason); end;
再利用kbmMW向导,建立一个Smart Web Service:
unit uHTTPService; // ========================================================================= // kbmMW - An advanced and extendable middleware framework. // by Components4Developers (http://www.components4developers.com) // // Service generated by kbmMW service wizard. // // INSTRUCTIONS FOR REGISTRATION/USAGE // ----------------------------------- // Please update the uses clause of the datamodule/form the TkbmMWServer is placed on by adding services unit name // to it. Eg. // // uses ...,kbmMWServer,YourServiceUnitName; // // Somewhere in your application, make sure to register the serviceclass to the TkbmMWServer instance. // This can be done by registering the traditional way, or by using auto registration. // // Traditional registration // ------------------------ // var // sd:TkbmMWCustomServiceDefinition; // .. // sd:=kbmMWServer1.RegisterService(yourserviceclassname,false); // // Set the last parameter to true if this is the default service. // // // Auto registration // ----------------- // Make sure that your service class is tagged with the [kbmMW_Service] attribute. // Then auto register all tagged services: // .. // kbmMWServer1.AutoRegisterServices; // // ----------------------------------------------- // // SPECIFIC HTTP SERVICE REGISTRATION INSTRUCTIONS // ----------------------------------------------- // Cast the returned service definition object (sd) to a TkbmMWHTTPServiceDefinition. eg: // // var // httpsd:TkbmMWHTTPServiceDefinition; // .. // httpsd:=TkbmMWHTTPServiceDefinition(sd) // httpsd.RootPath[mwhfcHTML]:='.'; // httpsd.RootPath[mwhfcImage]:='.'; // httpsd.RootPath[mwhfcJavascript]:='.'; // httpsd.RootPath[mwhfcStyleSheet]:='.'; // httpsd.RootPath[mwhfcOther]:='.'; // ----------------------------------------------- {$I kbmMW.inc} interface uses SysUtils, {$ifdef LEVEL6} Variants, {$else} Forms, {$endif} Classes, kbmMWSecurity, kbmMWServer, kbmMWServiceUtils, kbmMWHTTPStdTransStream, kbmMWGlobal, kbmMWCustomHTTPSmartService ,kbmMWRTTI ,kbmMWSmartServiceUtils; type [kbmMW_Service('flags:[listed]')] [kbmMW_Rest('path:/')] // Access to the service can be limited using the [kbmMW_Auth..] attribute. // [kbmMW_Auth('role:[SomeRole,SomeOtherRole], grant:true')] TWebSocketService = class(TkbmMWCustomHTTPSmartService) function kbmMWCustomHTTPSmartServiceUpgrade(Sender: TObject; const ARequestHelper, AResponseHelper: TkbmMWHTTPTransportStreamHelper; const ARequestedProtocols: string; var AAcceptedProtocol: string): Boolean; private { Private declarations } protected { Protected declarations } public { Public declarations } // HelloWorld function callable from both a regular client, // due to the optional [kbmMW_Method] attribute, // and from a REST client due to the optional [kbmMW_Rest] attribute. // The access path to the function from a REST client (like a browser)+ // is in this case relative to the services path. // In this example: http://...//helloworld // Access to the function can be limited using the [kbmMW_Auth..] attribute. // [kbmMW_Auth('role:[SomeRole,SomeOtherRole], grant:true')] [kbmMW_Rest('method:get, path:helloworld')] [kbmMW_Method] function HelloWorld:string; end; implementation uses kbmMWExceptions, uMain; {$R *.dfm} // Service definitions. //--------------------- function TWebSocketService.HelloWorld:string; begin Result:='Hello world'; end; function TWebSocketService.kbmMWCustomHTTPSmartServiceUpgrade(Sender: TObject; const ARequestHelper, AResponseHelper: TkbmMWHTTPTransportStreamHelper; const ARequestedProtocols: string; var AAcceptedProtocol: string): Boolean; begin AAcceptedProtocol:='websocket'; Result:=true; end; initialization TkbmMWRTTI.EnableRTTI(TWebSocketService); end.
OK,服务端就完成了!
原文地址:https://components4developers.blog/2022/08/28/kbmmw-websocket-1/