This is an experimental implementation of HTTP/1.1 and WebSocket client for OMRON's NX controllers. This HTTP client lacks functionality and is not of sufficient quality. However, it shows that it is possible to implement a practical HTTP client with a user program using Sysmac Studio and the NX controller. The Sysmac project contains several test programs. The HTTP client test program queries Beeceptor's HTTP echo server, and the WebSocket client test program exchanges data via WebSocket.org's WebSocket echo server. For details, please check this article (Japanese).
The HTTP client has the following restrictions.
- Can't use proxy
- Invalid responses can cause tasks to time out
Inquiries using HTTP(S) can be written as follows.
// POST /chat/api/v1 ContentType: application/json 20: IF NewHttpClientTask( Context:=iHttpContext, ClientTask:=iHttpClientTask) THEN HttpPost(Context:=iHttpContext, Url:='https://echo.free.beeceptor.com/chat/api/v1', KeepAlive:=FALSE, ClientTask:=iHttpClientTask); SetHttpHeader(Context:=iHttpContext, Key:='X-Api-Key', Value:='xxxxxx'); SetContentStr( Context:=iHttpContext, ContentType:='application/json', Content:='{"channel":"hell","name":"taker","msg":"Have you played Awaria?"}'); iPostTick := 0; InvokeHttpClientTask(Context:=iHttpContext, ClientTask:=iHttpClientTask); Inc(iState); END_IF; 21: CASE HttpClientTaskState(Context:=iHttpContext, ClientTask:=iHttpClientTask) OF HTTP_CLIENT_TASK_STATE_CLOSED: iState := iTransState; HTTP_CLIENT_TASK_STATE_RESPOND: CASE GetStatusCode(Context:=iHttpContext) OF 200: // OK iPostRspContentType := GetContentType(Context:=iHttpContext); GetContent(Context:=iHttpContext, Out:=iRspBinBody, Head:=0, Size=>iRspBinBodySize); iPostRspContent := AryToString(In:=iRspBinBody[0], Size:=iRspBinBodySize); iState := iTransState; 204: // No Content iState := iTransState; ELSE Inc(iState); END_CASE; HTTP_CLIENT_TASK_STATE_REQUESTING: Inc(iPostTick); HTTP_CLIENT_TASK_STATE_ERROR: GetHttpClientError(Context:=iHttpContext, Error=>iError, ErrorID=>iErrorID, ErrorIDEx=>iErrorIDEx); iState := iState + 7; END_CASE; The WebSocket client can be written as follows.
CASE iState OF 0: RingBuffer_init(Context:=iWriteBufferContext, Buffer:=iWriteBuffer); RingBuffer_init(Context:=iReadBufferContext, Buffer:=iReadBuffer); WebSocketClientService_init( Context:=iServiceContext, Url:='wss://echo.websocket.org/.ws', TLSSessionName:='TLSSession1', OptionNoDelay:=TRUE, SendThreshold:=0); iService.Enable := TRUE; Inc(iState); 1: IF WebSocketClientService_isActive(Context:=iServiceContext) THEN WebSocketClientService_getStreamContext( Context:=iServiceContext, WriteStreamContext=>iWriteStreamContext, ReadStreamContext=>iReadStreamContext); Inc(iState); END_IF; 2: CASE WebSocketClientService_getState(Context:=iServiceContext) OF WEBSOCKET_CLIENT_STATE#WCS_ACTIVE: // Receive messages. CASE WebSocketStream_on( Context:=iReadStreamContext, BufferContext:=iReadBufferContext, Buffer:=iReadBuffer, Data:=iRecvPayload, Head:=iRecvPayloadHead, Size=>iRecvPayloadSize, PayloadLength=>iPayloadLength, Done=>iDoneFrame) OF WEBSOCKET_FRAME_TYPE#WFT_TEXT: iRecvPayloadHead := iRecvPayloadHead + iRecvPayloadSize; IF iDoneFrame THEN iRecvMessageStr := AryToString(In:=iRecvPayload[0], Size:=iRecvPayloadHead); iRecvPayloadHead := 0; END_IF; END_CASE; // Send messages. IF iSend THEN WebSocketStream_writeText( Context:=iWriteStreamContext, BufferContext:=iWriteBufferContext, Buffer:=iWriteBuffer, Payload:=CONCAT(DtToString(GetTime()), '$L')); iSend := FALSE; END_IF; // Close the connection. IF iClose THEN WebSocketClientService_deactivate( Context:=iServiceContext, CloseCode:=1001); iClose := FALSE; Inc(iState); END_IF; WEBSOCKET_CLIENT_STATE#WCS_DEACTIVATING: Inc(iState); END_CASE; 3: iService.Enable := FALSE; Inc(iState); END_CASE; iService(Context:=iServiceContext, WriteBufferContext:=iWriteBufferContext, WriteBuffer:=iWriteBuffer, ReadBufferContext:=iReadBufferContext, ReadBuffer:=iReadBuffer); To use this project, the following environment is required.
| Item | Requirement |
|---|---|
| Controller | NX1 or NX5 |
| Sysmac Studio | Latest version recommended |
| Network | Internet connection must be possible |
This project was developed using the following environment.
| Item | Version |
|---|---|
| Controller | NX102-9000 Ver 1.64 |
| Sysmac Studio | Ver.1.62 |
The HTTP client test program (Test_HttpEcho) queries Beeceptor's HTTP echo server. There may be some restrictions when accessing from a network that is not under your control. If possible, use a test network to ensure there are no constraints.
Set the controller model of this project to match the controller model to be used, and to enable Internet connection and name resolution. At least the gateway and DNS server settings are required.
Set the controller to program mode to prevent unintended operation and to configure secure sockets.
Keep the controller in program mode to prevent the program from running.
Register a TLS session with ID 0 and no client certificate. Do the following while online to the controller.
Paste the following into Watch window.
LIB Test_HttpEcho.iGetRspContent LIB Test_HttpEcho.iPostRspContent LIB Test_HttpEcho.iPostFormRspContent LIB Test_HttpEcho.iPutRspContent LIB Test_HttpEcho.iPatchRspContent LIB Test_HttpEcho.iDeleteRspContent The moment you switch to driving mode, it starts making requests to the server.
If there is a response from the server, the HTTP response will be displayed as shown below.
If an error occurs, there are the following possibilities:
- Incorrect secure socket settings
Check if the ID is0. - HTTP echo server is down
Ping the HTTP echo server from your device and check the response. - Not connected to the Internet or unable to resolve name
Check the route to the HTTP echo server with tracert.
The WebSocket client test program (Test_WebSocketEcho) sends and receives data via the WebSocket echo server at WebSocket.org. There may be some restrictions when accessing from a network that is not under your control. If possible, use a test network to ensure there are no constraints.
Set the controller model of this project to match the controller model to be used, and to enable Internet connection and name resolution. At least the gateway and DNS server settings are required.
Set the controller to program mode to prevent unintended operation and to configure secure sockets.
Keep the controller in program mode to prevent the program from running.
Register a TLS session with ID 1 and no client certificate.
The moment you switch to driving mode, it starts making requests to the server.
If the program runs correctly, it will eventually receive the string "done\n" and exit.
If an error occurs, there are the following possibilities:
- Incorrect secure socket settings
Check if the ID is1. - WebSocket echo server is down
Ping the WebSocket echo server from your device and check the response. - Not connected to the Internet or unable to resolve name
Check the route to the WebSocket echo server with tracert.


