红鱼儿

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/

posted on 2022-08-31 07:08  红鱼儿  阅读(335)  评论(0编辑  收藏  举报