首页 > 其他分享 >cross socket ICrossHttpServer

cross socket ICrossHttpServer

时间:2023-06-15 16:22:37浏览次数:48  
标签:begin end socket req cross var const ICrossHttpServer Ctxt

cross socket ICrossHttpServer

cross socket是delphi跨平台的一个socket库。

/// <author>cxg 2023-2-12</author>
/// TStream(ARequest.body),auto be free

unit sock.CrossHttpSvr;

interface

uses
  system.JSON, json.help, keyValue.serialize, api.router,
  Net.CrossSocket.Base, global, yn.log, Net.CrossHttpServer,
  Net.CrossSslSocket, Net.CrossSslDemoCert, System.Math,
  System.IniFiles, System.SysUtils, System.Classes;

var
  BinApis: TJSONObject;    //二进制API
  RestApis: TJSONObject;   //REST API,包括json,protobuf

const  //content-type
  cBin = 'application/octet-stream; charset=utf-8';
  cJson = 'application/json; charset=utf-8';
  cProtobuf = 'application/protobuf; charset=utf-8';

type
  TcrossHttpSvr = class
  private
    FHttpServer: ICrossHttpServer;
    FShutdown: Boolean;
    procedure Process;
  public
    constructor Create; overload;
    destructor Destroy; override;
  public
    procedure Start;
    procedure Stop;
    property HttpServer: ICrossHttpServer read FHttpServer;
  end;

implementation

function strof(const aStream: TStream): RawByteString; overload;
begin
  SetLength(Result, aStream.Size);
  aStream.Position := 0;
  aStream.Read(Result[1], aStream.Size);
end;

function ReadJsonFile(const FileName: string): string;
begin
  var f: TStringList := TStringList.Create;
  f.LoadFromFile(FileName, TEncoding.UTF8);
  Result := f.Text;
  f.Free;
end;

procedure setHeader(const Ctxt: ICrossHttpResponse; const ContentType: string);
begin
  Ctxt.Header['Access-Control-Allow-Origin'] := '*';
  Ctxt.Header['Access-Control-Allow-Methods'] := '*';
  Ctxt.Header['Access-Control-Allow-Headers'] := '*';
  Ctxt.ContentType := ContentType;
end;

procedure router(const Ctxt: ICrossHttpRequest; const Ctxt2: ICrossHttpResponse);
begin
  if Pos('/bin', Ctxt.RawPathAndParams) > 0 then      //二进制 API
  begin
    setHeader(Ctxt2, cBin);
    var req: TSerialize := tserialize.Create;
    var res: TSerialize := tserialize.Create;
    var ms: TStream := TStream(Ctxt.Body);
    if ms <> nil then
      req.unMarshal(ms);
    var url: string := Ctxt.RawPathAndParams;
    var arr: TArray<string> := url.Split(['/']);
    var funcName: string := arr[2];
    var ja: TJSONArray := BinApis.A['bin'];
    for var i: Integer := 0 to ja.Count - 1 do
    begin
      var o: TJSONObject := ja.Items[i] as TJSONObject;
      if o.S['funcname'] = funcName then
      begin
        RouterAPI(o.S['classname'], o.S['funcname'], [req, res]);
        Break;
      end;
    end;
    Ctxt2.Send(res.marshal2,
      procedure(const AConnection: ICrossConnection; const ASuccess: Boolean)
      begin
        req.Free;
        res.Free;
      end);
  end
  else if Pos('/rest', Ctxt.RawPathAndParams) > 0 then    //JSON API
  begin
    setHeader(Ctxt2, cJson);
    var url: string := Ctxt.RawPathAndParams;
    var arr: TArray<string> := url.Split(['/']);
    var resource: string := arr[2];
    var req: TSerialize := tserialize.Create;
    var res: TSerialize := tserialize.Create;
    req.asStr['url'] := url;
    var ms: TStream := TStream(Ctxt.Body);
    var body: RawByteString;
    if ms <> nil then
      body := strof(ms);
    req.asStr['body'] := body;
    req.asStr['type'] := 'json';
    var ja: TJSONArray := RestApis.A[resource];
    for var i: Integer := 0 to ja.Count - 1 do
    begin
      var o: TJSONObject := ja.Items[i] as TJSONObject;
      if o.S['method'] = Ctxt.Method then
      begin
        RouterAPI(o.S['classname'], o.S['funcname'], [req, res]);
        Break;
      end;
    end;
    Ctxt2.Send(UTF8Encode(res.asStr['res']),
      procedure(const AConnection: ICrossConnection; const ASuccess: Boolean)
      begin
        req.Free;
        res.Free;
      end);
  end
  else if Pos('/protobuf', Ctxt.RawPathAndParams) > 0 then   //PROTOBUF API
  begin
    setHeader(Ctxt2, cProtobuf);
    var url: string := Ctxt.RawPathAndParams;
    var arr: TArray<string> := url.Split(['/']);
    var resource: string := arr[2];
    var req: TSerialize := tserialize.Create;
    var res: TSerialize := tserialize.Create;
    req.asStr['url'] := url;
    var ms: TStream := TStream(Ctxt.Body);
    var body: TBytes;
    if ms <> nil then
      strof(ms);
    req.asBytes['body'] := body;
    req.asStr['type'] := 'protobuf';
    var ja: TJSONArray := RestApis.A[resource];
    for var i: Integer := 0 to ja.Count - 1 do
    begin
      var o: TJSONObject := ja.Items[i] as TJSONObject;
      if o.S['method'] = Ctxt.Method then
      begin
        RouterAPI(o.S['classname'], o.S['funcname'], [req, res]);
        Break;
      end;
    end;
    Ctxt2.Send(res.asBytes['res'],
      procedure(const AConnection: ICrossConnection; const ASuccess: Boolean)
      begin
        req.Free;
        res.Free;
      end);
  end;
end;

constructor TcrossHttpSvr.Create;
begin
  var ini: TIniFile := TIniFile.create(SvrCfg);
  var threadnum: Integer := ini.readinteger('config', 'threadnum', 32);
  if threadnum > 256 then
    threadnum := 256;
  var ssl: Boolean := ini.readbool('config', 'ssl', False);
  FHttpServer := TCrossHttpServer.create(threadnum, ssl); // New http server
  if FHttpServer.SSL then
  begin
    FHttpServer.SetCertificate(SSL_SERVER_CERT);
    FHttpServer.SetPrivateKey(SSL_SERVER_PKEY);
  end;

  FHttpServer.Addr := IPv4v6_ALL;
  FHttpServer.Port := ini.readinteger('config', 'httpport', 0); // port
  ini.Free;
  {$IFDEF console}
  Writeln('New cross http server');
  Writeln('Http port: ', FHttpServer.Port);
  Writeln('Thread num: ', threadnum);
  {$ENDIF}
  FHttpServer.Compressible := True; // zip?
  Process;
  Self.Start;
end;

destructor TcrossHttpSvr.Destroy;
begin
  Self.Stop;
  FHttpServer := nil;
  inherited;
end;

procedure TcrossHttpSvr.Start;
begin
  FHttpServer.Start;
end;

procedure TcrossHttpSvr.Stop;
begin
  FHttpServer.Stop;
  FShutdown := True;
  Sleep(150);
end;

procedure TcrossHttpSvr.Process;
begin
  try
    FHttpServer.All('*',
      procedure(const ARequest: ICrossHttpRequest; const AResponse: ICrossHttpResponse)
      begin
        router(ARequest, AResponse);
      end);
  except
    on E: Exception do
    begin
      writelog('TcrossHttpSvr.Process()' + E.message);
    end;
  end;
end;

initialization
  binapis := TJSONObject.Create;
  restapis := TJSONObject.Create;
  binapis.Parse(ReadJsonFile(ExtractFilePath(ParamStr(0)) + 'binrouter.json'));
  restapis.Parse(ReadJsonFile(ExtractFilePath(ParamStr(0)) + 'restrouter.json'));

finalization
  FreeAndNil(binapis);
  FreeAndNil(restapis);

end.

  

标签:begin,end,socket,req,cross,var,const,ICrossHttpServer,Ctxt
From: https://www.cnblogs.com/hnxxcxg/p/17483253.html

相关文章

  • webSocket和Socke
    一、webSocket和Socket的概念介绍1、socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。2、WebSocket协议是基于TCP的一种新的网络协议,和http协议一样属于应用层协议,是一种让客户端和......
  • C#-网络通讯框架(一)-HPSocket
    一、简介这里加一张图片 二、基础使用这里加一张图片1、TCP 2、UDP三、与线程池一起使用(TCP) 四、HPSocket扩展Easy组件(部分)  HPSocket.Net目前提供6个Easy组件和2个WebSocket组件ITcpPortForwardingIHttpEasyServerIHttpsEasyServerIHttpEasyAgentIHttpsEas......
  • KingbaseES数据库改写SQL Server数据库CROSS APPLY和OUTER APPLY
     一、功能介绍:CROSSAPPLY和OUTERAPPLY是SQLServer中的一种连接操作,类似于JOIN语句可以将一张表与一个表函数或一个子查询进行关联。表函数是一种返回一个表类型的数据的函数,子查询是一个嵌套在外部查询中的查询。它们可以与表值函数或子查询配合使用,返回左表和右表的匹配结......
  • nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by prot
    nginx:[emerg]socket()[::]:80failed(97:Addressfamilynotsupportedbyprotocol),遇到这个问题,不用多想,基本都是配置了IPv6监听导致,也就是如下配置server{listen80default_server;listen[::]:80default_server;listen[::]:8......
  • 5.26日学习总结之网络编程socket
    Pythonsocket编程在网络上的教程较少,菜鸟中也只是给出了一小段描述,在此我推荐白羽黑夜socket编程|白月黑羽(byhy.net)其中的描写非常详细,本人也是在此学习的。socket又被称作套接字,可以简单的看作是两个地址(ip,port地址)之间通过socket的函数来进行传递数据。socket在客户端......
  • Python标准库socketserver使用线程混入实现异步TCP服务器
    功能描述:使用Python标准库socketserver中提供的ThreadingTCPServer实现异步TCP服务端程序,隐藏线程创建与管理细节,自动为每个客户端连接创建线程并处理数据。服务端代码: 客户端代码:......
  • Python标准库socketserver实现UDP协议时间服务器
    Python标准库socketserver进行了更高一级的封装,非常适合服务端代码的编写,本文通过改写时间服务器的案例来演示标准库socketserver的用法,更多案例最近会陆续推送。服务端代码: 客户端代码: 运行情况:   ......
  • webSocket-全双工通信协议
    1、springboot2.0集成webSocket项目结构maven依赖<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.6.RELEASE</version>&......
  • websocket
    1.WebSocket介绍WebSocket是一种网络通信协议。RFC6455定义了它的通信标准。WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。HTTP协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务......
  • 简单的WebSocket对话
    步骤选择一个WebSocket服务器,这里选择到的模块是ws模块npmiws创建一个WebSocket服务器新建一个server.js编写如下代码constWebSocket=require('ws');constwss=newWebSocket.Server({port:3000});wss.on('connection',(socket)=>{console.l......