Note:This document describes how to support WebSocket for event-triggered functions. Currently, HTTP-triggered functions already supports the native WebSocket protocol.
WebSocket is a new TCP-based network protocol. It implements full-duplex communication between browser and server, i.e., allowing server to actively send information to client. In contrast, a server using the traditional HTTP protocol only allows a client to get the data that needs to be pushed through polling or long polling.
Since SCF is stateless and trigger-based (i.e., it will be triggered only when an event arrives), in order to implement WebSocket, SCF is used in conjunction with API Gateway to sustain and maintain the connection with the client through API Gateway. You can assume that API Gateway and SCF work together to implement the server. When sent by the client, a message is first passed to API Gateway, which then triggers the SCF function. When the server function sends a message to the client, the function first posts the message to the reverse push link of API Gateway, which then pushes the message to the client. The specific implementation architecture is as follows:
The entire lifecycle of WebSocket mainly consists of the following events:
SCF and API Gateway handle the events throughout the lifecycle of WebSocket as follows:
Therefore, the interaction between API Gateway and SCF needs to be sustained by three types of functions:
secConnectionID
of the WebSocket connection. The secConnectionID
is usually recorded in the persistent storage in this function for reverse push of subsequent data.secConnectionID
. The secConnectionID
is usually cleaned from the persistent storage in this function.secConnectionID
of the connection and the data sent. Business data is usually processed in this function. For example, it determines whether to push data to other secConnectionID
values in the persistent storage.Note:When you need to actively push data to a
secConnectionID
or disconnect asecConnectionID
, the reverse push address of API Gateway has to be used.
{
"requestContext": {
"serviceName": "testsvc",
"path": "/test/{testvar}",
"httpMethod": "GET",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"identity": {
"secretId": "abdcdxxxxxxxsdfs"
},
"sourceIp": "10.0.2.14",
"stage": "prod",
"websocketEnable":true
},
"websocket":{
"action":"connecting",
"secConnectionID":"xawexasdfewezdfsdfeasdfffa==",
"secWebSocketProtocol":"chat,binary",
"secWebSocketExtensions":"extension1,extension2"
}
}
Structure Name | Content |
---|---|
requestContext | Configuration information, request ID, authentication information, and source information of API Gateway where the request comes from, including:
|
websocket | Details of connection establishment, including:
|
Note:The content of
requestContext
may be increased significantly during API Gateway iteration. At present, it is guaranteed that the content of the data structure will only be increased but not reduced, so that the existing structure will not be compromised.
When the registration function receives the connection establishment request, it needs to return the response message of whether to agree to establish the connection to API Gateway at the end of function handling. The response body must be in JSON format as shown in the sample below:
{
"errNo":0,
"errMsg":"ok",
"websocket":{
"action":"connecting",
"secConnectionID":"xawexasdfewezdfsdfeasdfffa==",
"secWebSocketProtocol":"chat,binary",
"secWebSocketExtensions":"extension1,extension2"
}
}
Structure Name | Content |
---|---|
errNo | Integer; required. Response error code. If `errNo` is 0, the handshake succeeded, and the connection was allowed to be established. |
errMsg | String; required. Cause of error. If `errNo` is not 0, this field will take effect. |
websocket | Details of connection establishment, including:
|
Note:
- If the SCF request times out, it will be deemed by default that the connection establishment failed.
- When API Gateway receives the response message from SCF, it will check the HTTP response code first. If the response code is 200, it will parse the response body; otherwise, it will deem that SCF failed and connection establishment was refused.
When the client sends data through WebSocket, API Gateway will encapsulate the agreed JSON data structures in the request body and send it to the transfer function in the HTTP POST method. You can get the request body from the function's event. Below is a sample:
{
"websocket":{
"action":"data send",
"secConnectionID":"xawexasdfewezdfsdfeasdfffa==",
"dataType":"text",
"data":"xxx"
}
}
The data structures are as detailed below:
Parameter | Content |
---|---|
websocket | Details of data transfer. |
action | Action of this request, such as "data send" in this document. |
secConnectionID | A string that identifies the ID of the WebSocket connection. The original length is 128 bits, which is a Base64-encoded string with a total of 32 characters. |
dataType | Type of the transferred data.
|
data | Transferred data. If `dataType` is `binary`, it will be a Base64-encoded binary stream; if `dataType` is `text`, it will be a string. |
After the transfer function finishes executing, it will return an HTTP response to API Gateway which will act according to the response code:
Note:API Gateway does not handle the content in the response body.
When SCF needs to push data to the client or actively disconnect, it can initiate a request, encapsulate the data in the request body, and send it to the reverse push address of API Gateway in the POST method. The request body must be in JSON format, as shown in the sample below:
{
"websocket":{
"action":"data send", // Send data to the client
"secConnectionID":"xawexasdfewezdfsdfeasdfffa==",
"dataType":"text",
"data":"xxx"
}
}
{
"websocket":{
"action":"closing", // Send the disconnection request
"secConnectionID":"xawexasdfewezdfsdfeasdfffa=="
}
}
Field | Content |
---|---|
websocket | Details of data transfer. |
action | Action of this request, which can be data send or closing :
|
secConnectionID | A string that identifies the ID of the WebSocket connection. The original length is 128 bits, which is a Base64-encoded string with a total of 32 characters. |
dataType | Type of the transferred data, including two types:
|
data | Transferred data:
|
After the callback is over, the result of the callback can be determined based on the response code of API Gateway:
In addition, the response body in JSON format can be obtained in the response result as shown in the sample below:
{
"errNo":0,
"errMsg":"ok"
}
The data structures are as detailed below:
Field | Content |
---|---|
errNo | Integer; response error code. 0 means success. |
errMsg | String; cause of error. |
When the client actively initiates a WebSocket disconnection request, API Gateway will encapsulate the agreed upon JSON data structures in the request body and send it to the cleanup function in the HTTP POST method. You can get the request body from the function's event. Below is a sample:
{
"websocket":{
"action":"closing",
"secConnectionID":"xawexasdfewezdfsdfeasdfffa=="
}
}
The data structures are as detailed below:
Field | Content |
---|---|
websocket | Details of disconnection. |
action | Action of this request, which is "closing" here. |
secConnectionID | String. It identifies the ID of the WebSocket connection. The original length is 128 bits, which is a Base64-encoded string with a total of 32 characters. |
Note:In the cleanup function, you can get the
secConnectionID
from the event and delete the ID from the persistent storage (such as a database).
After the cleanup function finishes executing, it will return an HTTP response to API Gateway, which will act according to the response code:
Note:API Gateway does not handle the content in the response body.
Please see Downstream data callback. SCF can initiate a request in the function, encapsulate the following data structures in the request body, and send it to the reverse push address of API Gateway in the POST method.
{
"websocket":{
"action":"closing", // Send the disconnection request
"secConnectionID":"xawexasdfewezdfsdfeasdfffa=="
}
}
Note:When actively disconnecting the link with the client, you need to get the
secConnectionID
of the client's WebSocket, enter it in the data structure, and then delete the ID from the persistent storage (such as a database).
Was this page helpful?