wasm.websocket.api.pas 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. {
  2. This file is part of the Free Component Library
  3. Webassembly Websocket API - imported functions and structures.
  4. Copyright (c) 2024 by Michael Van Canneyt [email protected]
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit wasm.websocket.api;
  12. {$mode ObjFPC}{$H+}
  13. interface
  14. uses
  15. {$IFDEF FPC_DOTTEDUNITS}
  16. System.SysUtils,
  17. {$ELSE}
  18. sysutils,
  19. {$ENDIF}
  20. wasm.logger.api,
  21. wasm.websocket.shared;
  22. Type
  23. TWasmWebSocketLogLevel = TWasmLogLevel;
  24. TWasmWebSocketLogLevels = set of TWasmWebsocketLogLevel;
  25. const
  26. wllTrace = wasm.logger.api.wllTrace;
  27. wllDebug = wasm.logger.api.wllDebug;
  28. wllInfo = wasm.logger.api.wllInfo;
  29. wllWarning = wasm.logger.api.wllWarning;
  30. wllError = wasm.logger.api.wllError;
  31. wllCritical = wasm.logger.api.wllCritical;
  32. function __wasm_websocket_allocate(
  33. aURL : PByte;
  34. aUrlLen : Longint;
  35. aProtocols : PByte;
  36. aProtocolLen : Longint;
  37. aUserData : Pointer;
  38. aWebsocketID : TWasmWebSocketID) : TWasmWebsocketResult; external websocketExportName name websocketFN_Allocate;
  39. function __wasm_websocket_close(
  40. aWebsocketID : TWasmWebSocketID;
  41. aCode : Longint;
  42. aReason : PByte;
  43. aReasonLen : Longint) : TWasmWebsocketResult; external websocketExportName name websocketFN_Close;
  44. function __wasm_websocket_send(
  45. aWebsocketID : TWasmWebSocketID;
  46. aData : PByte;
  47. aDataLen : Longint;
  48. aType : Longint
  49. ) : TWasmWebsocketResult; external websocketExportName name websocketFN_Send;
  50. function __wasm_websocket_deallocate(
  51. aWebsocketID : TWasmWebSocketID) : TWasmWebsocketResult; external websocketExportName name websocketFN_DeAllocate;
  52. Type
  53. TWasmWebsocketErrorCallback = procedure(aWebSocketID : TWasmWebSocketID; aUserData : Pointer);
  54. TWasmWebsocketMessageCallback = procedure(aWebSocketID : TWasmWebSocketID; aUserData : Pointer; aMessageType : TWasmWebSocketMessageType; aMessage : TBytes);
  55. TWasmWebsocketCloseCallback = procedure(aWebSocketID : TWasmWebSocketID; aUserData : Pointer; aCode: Longint; const aReason : String; aClean : Boolean);
  56. TWasmWebsocketOpenCallback = procedure(aWebSocketID : TWasmWebSocketID; aUserData : Pointer);
  57. TWasmWebsocketLogHook = procedure (Level : TWasmWebSocketLogLevel; const Msg : string) of object;
  58. TWasmWebsocketReleasePacketCallback = procedure(aWebsocketID : TWasmWebSocketID; aUserData : Pointer; aPacket : Pointer; var Result : boolean);
  59. // Callee is responsible for freeing incoming buffers
  60. Function __wasm_websocket_allocate_buffer(aWebsocketID : TWasmWebSocketID; aUserData : Pointer; aBufferLen : Longint) : Pointer;
  61. Function __wasm_websocket_release_packet(aWebsocketID : TWasmWebSocketID; aUserData : Pointer; aPacket : Pointer) : longint;
  62. Function __wasm_websocket_on_error (aWebsocketID : TWasmWebSocketID; aUserData : Pointer) : TWebsocketCallBackResult;
  63. Function __wasm_websocket_on_message (aWebsocketID : TWasmWebSocketID; aUserData : Pointer; aMessageType : TWasmWebSocketMessageType; aMessage : Pointer; aMessageLen : Integer) : TWebsocketCallBackResult;
  64. Function __wasm_websocket_on_open (aWebsocketID : TWasmWebSocketID; aUserData : Pointer) : TWebsocketCallBackResult;
  65. Function __wasm_websocket_on_close (aWebsocketID : TWasmWebSocketID; aUserData : Pointer; aCode: Longint; aReason : PByte; aReasonLen : Longint; aClean : Longint) : TWebsocketCallBackResult;
  66. procedure __wasmwebsocket_log(level : TWasmLogLevel; const Msg : String);
  67. procedure __wasmwebsocket_log(level : TWasmLogLevel; const Fmt : String; const Args : Array of const);
  68. var
  69. WebSocketLogEnabled : Boolean;
  70. WebSocketErrorCallback : TWasmWebsocketErrorCallback;
  71. WebSocketMessageCallback : TWasmWebsocketMessageCallback;
  72. WebSocketCloseCallback : TWasmWebsocketCloseCallback;
  73. WebSocketOpenCallback : TWasmWebsocketOpenCallback;
  74. WebSocketReleasePackageCallBack : TWasmWebsocketReleasePacketCallback;
  75. implementation
  76. procedure __wasmwebsocket_log(level : TWasmWebSocketLogLevel; const Msg : String);
  77. begin
  78. if not WebSocketLogEnabled then
  79. exit;
  80. __wasm_log(level,'websocket',msg);
  81. end;
  82. procedure __wasmwebsocket_log(level : TWasmWebSocketLogLevel; const Fmt : String; const Args : Array of const);
  83. begin
  84. if not WebSocketLogEnabled then
  85. exit;
  86. __wasm_log(level,'websocket',Fmt,Args);
  87. end;
  88. Function __wasm_websocket_allocate_buffer(aWebsocketID : TWasmWebSocketID; aUserData : Pointer; aBufferLen : Longint) : Pointer;
  89. begin
  90. // Silence compiler warning
  91. if (aWebSocketID=0) or (aUserData=Nil) then ;
  92. Result:=GetMem(aBufferLen);
  93. end;
  94. procedure LogError(const aOperation : String; aError : Exception);
  95. begin
  96. __wasmwebsocket_log(wllError,SafeFormat('Error %s during %s callback: %s',[aError.ClassName,aOperation,aError.Message]));
  97. end;
  98. Function __wasm_websocket_on_error (aWebsocketID : TWasmWebSocketID; aUserData : Pointer) : TWebsocketCallBackResult;
  99. begin
  100. if not assigned(WebSocketErrorCallback) then
  101. Exit(WASMWS_CALLBACK_NOHANDLER);
  102. try
  103. WebsocketErrorCallBack(aWebsocketID,aUserData);
  104. Result:=WASMWS_CALLBACK_SUCCESS;
  105. except
  106. On E : exception do
  107. begin
  108. LogError('error',E);
  109. Result:=WASMWS_CALLBACK_ERROR;
  110. end;
  111. end;
  112. end;
  113. Function __wasm_websocket_on_message (aWebsocketID : TWasmWebSocketID; aUserData : Pointer; aMessageType : TWasmWebSocketMessageType; aMessage : Pointer; aMessageLen : Integer) : TWebsocketCallBackResult;
  114. var
  115. Buf : TBytes;
  116. begin
  117. Buf:=[];
  118. try
  119. if not assigned(WebSocketMessageCallback) then
  120. Exit(WASMWS_CALLBACK_NOHANDLER);
  121. try
  122. SetLength(Buf,aMessageLen);
  123. if aMessageLen>0 then
  124. Move(aMessage^,Buf[0],aMessageLen);
  125. WebsocketMessageCallBack(aWebsocketID,aUserData,aMessageType,Buf);
  126. Result:=WASMWS_CALLBACK_SUCCESS;
  127. except
  128. On E : exception do
  129. begin
  130. LogError('message',E);
  131. Result:=WASMWS_CALLBACK_ERROR;
  132. end;
  133. end;
  134. finally
  135. FreeMem(aMessage);
  136. end;
  137. end;
  138. Function __wasm_websocket_on_open (aWebsocketID : TWasmWebSocketID; aUserData : Pointer) : TWebsocketCallBackResult;
  139. begin
  140. if not assigned(WebSocketOpenCallback) then
  141. Exit(WASMWS_CALLBACK_NOHANDLER);
  142. try
  143. WebsocketOpenCallBack(aWebsocketID,aUserData);
  144. Result:=WASMWS_CALLBACK_SUCCESS;
  145. except
  146. On E : exception do
  147. begin
  148. LogError('message',E);
  149. Result:=WASMWS_CALLBACK_ERROR;
  150. end;
  151. end;
  152. end;
  153. Function __wasm_websocket_on_close (aWebsocketID : TWasmWebSocketID; aUserData : Pointer; aCode: Longint; aReason : PByte; aReasonLen : Longint; aClean : Longint) : TWebsocketCallBackResult;
  154. var
  155. lReason : String;
  156. Buf : TBytes;
  157. lClean : Boolean;
  158. begin
  159. Buf:=[];
  160. try
  161. if not assigned(WebSocketCloseCallback) then
  162. Exit(WASMWS_CALLBACK_NOHANDLER);
  163. try
  164. lClean:=(aClean=0);
  165. SetLength(Buf,aReasonLen);
  166. Move(aReason^,Buf[0],aReasonLen);
  167. {$IF SIZEOF(CHAR)=1}
  168. lReason:=TEncoding.UTF8.GetAnsiString(Buf);
  169. {$ELSE}
  170. lReason:=TEncoding.UTF8.GetString(Buf);
  171. {$ENDIF}
  172. WebsocketCloseCallBack(aWebsocketID,aUserData,aCode,lReason,lClean);
  173. Result:=WASMWS_CALLBACK_SUCCESS;
  174. except
  175. On E : exception do
  176. begin
  177. LogError('message',E);
  178. Result:=WASMWS_CALLBACK_ERROR;
  179. end;
  180. end;
  181. finally
  182. FreeMem(aReason);
  183. end;
  184. end;
  185. Function __wasm_websocket_release_packet(aWebsocketID : TWasmWebSocketID; aUserData : Pointer; aPacket : Pointer) : longint;
  186. var
  187. lRes : Boolean;
  188. begin
  189. lRes:=Assigned(WebSocketReleasePackageCallBack);
  190. if lRes then
  191. WebSocketReleasePackageCallBack(aWebsocketID,aUserData,aPacket,lRes);
  192. Result:=Ord(Not lRes); // 0 is OK, 1 is error.
  193. end;
  194. exports
  195. __wasm_websocket_allocate_buffer,
  196. __wasm_websocket_release_packet,
  197. __wasm_websocket_on_error,
  198. __wasm_websocket_on_message,
  199. __wasm_websocket_on_open,
  200. __wasm_websocket_on_close;
  201. end.