dg-lab-opensource-english/socket
2026-03-03 23:58:52 +01:00
..
BackEnd(Node) Update project status to BETA 2026-03-03 23:58:52 +01:00
FrontEnd(Html+Css+Js) Update project status to BETA 2026-03-03 23:58:52 +01:00
QA Translate to British English 2026-03-03 23:01:01 +01:00
DG_WAVES_V2_V3_simple.js Translate to British English 2026-03-03 23:01:01 +01:00
docker-compose.yml Add Docker support and frontend auto-reconnect 2026-03-03 23:34:04 +01:00
Quick Experience Guide.md feat 快速体验md 2024-11-27 15:23:51 +08:00
Quick_Experience.md Translate to British English 2026-03-03 23:01:01 +01:00
README.md Update project status to BETA 2026-03-03 23:58:52 +01:00
ws_service_core_method_explanation_JavaScript.md Translate to British English 2026-03-03 23:01:01 +01:00

SOCKET Control - Control End Open Source (BETA)

Note: The recent additions including Docker Support, Latency Monitoring, and Real-time Waveform Visualization are currently in BETA and have not been field-tested with DG-LAB hardware.

Update

time : 2025-03-15

desc:

Added ws service core method explanation - JavaScript

Update

time : 2024-09-14

desc :

Added QA:

English_QA Chinese_QA

Description

The SOCKET control function is a feature where the DG-LAB APP connects to an external third-party control end through a Socket service, and the control end sends data commands to the APP via SOCKET to make the Coyote output pulses. Developers can control the Coyote in a local area network or public network environment through webpages, games, scripts, or other terminals.

This function only supports Coyote Pulse Host 3.0.

Project

The official website example we provide is divided into two parts: the front-end control part (logical control, data display, behavioural operations, command data generation, etc.) and the SOCKET back-end part (relationship binding, data forwarding, etc.).

The scheme we designed is an N(APP Terminal)-SOCKET Service-N(Third-party Terminal) N-to-N mode, making it convenient for control ends made by developers to be used by multiple people simultaneously.

Project Structure

/socket/BackEnd(Node) -> SOCKET control back-end code, deployment document is available at /socket/BackEnd(Node)/document.txt

/socket/FrontEnd(Html+Css+Js) -> SOCKET control front-end code, deployment document is available at /socket/FrontEnd(Html+Css+Js)/document.txt

Project Structure

Connection Process Between Both Ends

Because the scheme we designed is an N-to-N mode, the two ends need to be connected together through a relationship binding process.

Connection Process Between Both Ends

APP Receiving Protocol

General Rules

  1. All messages are entirely in JSON format.
  2. JSON format: {"type":"xxx","clientId":"xxx","targetId":"xxx","message":"xxx"}
  3. type commands:
    1. heartbeat -> Heartbeat packet data
    2. bind -> ID relationship binding
    3. msg -> Data commands like waveform dispatch/intensity change/queue clearing, etc.
    4. break -> Connection disconnected
    5. error -> Service error
  4. clientID: Third-party terminal ID
  5. targetId: APP ID
  6. message: Message/Command
  7. The maximum character length of JSON data is 1950. If this length is exceeded, the APP will discard the message upon receipt.
  8. Except for the JSON data targetId returned by SOCKET to the terminal during a SOCKET connection which can be empty, all other commands must strictly and solely contain these 4 keys: type, clientId, targetId, message, and the values cannot be empty.
  9. The ID generated by the SOCKET service must be guaranteed unique. A 32-bit length (uuidV4) is recommended.

Relationship Binding

  1. Binding of SOCKET channel and terminal: After the terminal or APP connects to the SOCKET service, a unique ID is generated, bound with the websocket object of the terminal or APP, stored in a Map, and the ID is returned to the terminal or APP.

    Data returned by SOCKET to the terminal or APP: {"type":"bind","clientId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","targetId":"","message":"targetId"}

    When the terminal or APP receives type = bind, message = targetID, it indicates that the clientId returned by the SOCKET service is the ID of the current terminal or APP, which should be saved locally.

  2. Relationship binding of both terminals: After the DG-LAB APP sends the IDs of both terminals to the SOCKET service, the service binds the two IDs and stores them in a Map.

    ID data sent upwards by the APP: {"type":"bind","clientId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","targetId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","message":"DGLAB"}

    When the SOCKET service receives type = bind, message = DGLAB, and both clientId and targetId are not empty, it will bind the clientId (third-party terminal ID) and targetId (APP ID).

  3. The binding result is dispatched by the SOCKET service to the terminals or APPs corresponding to the two IDs in the binding relationship.

    Result data dispatched by SOCKET: {"type":"bind","clientId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","targetId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","message":"200"}

    When the terminal or APP receives type = bind, message = 200 (or other specified data, see error codes for details), it executes the corresponding UI logic.

Receiving Intensity Data

When the channel intensity or intensity upper limit in the APP changes, it will synchronise the latest channel intensity and intensity upper limit upwards.

APP sends intensity data upwards: {"type":"msg","clientId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","targetId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","message":"strength-x+x+x+x"}

SOCKET forwards the JSON to the third-party terminal according to the corresponding ID. When the terminal receives data with type = msg, message = strength-x+x+x+x, it updates the UI (updates the latest device channel intensity and intensity upper limit).

Command explanation:

  1. strength-A channel intensity+B channel intensity+A intensity upper limit+B intensity upper limit
  2. The value range for channel intensity and intensity upper limit is 0 to 200.

Example:

Data: {"type":"msg","clientId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","targetId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","message":"strength-11+7+100+35"}

Explanation: strength-11+7+100+35 means: current device A channel intensity=11, B channel intensity=7, A channel intensity upper limit=100, B channel intensity upper limit=35.

Intensity Operation

When a third-party terminal wants to modify the device channel intensity, it sends a specified JSON command.

Terminal sends intensity operation data downwards: {"type":"msg","clientId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","targetId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","message":"strength-x+x+x"}

The SOCKET service forwards the JSON to the APP according to the corresponding ID. When the APP receives data with type = msg, message = strength-x+x+x, it executes the specified intensity change operation.

Command explanation:

  1. strength-channel+intensity change mode+value
  2. Channel: 1 - A channel; 2 - B channel
  3. Intensity change mode: 0 - channel intensity decrease; 1 - channel intensity increase; 2 - channel intensity changes to specified value
  4. Value: an integer in the range (0 ~ 200)

Examples:

  1. A channel intensity + 5 -> strength-1+1+5
  2. B channel intensity drops to zero -> strength-2+2+0
  3. B channel intensity - 20 -> strength-2+0+20
  4. A channel intensity specified as 35 -> strength-1+2+35
  • Tips: Commands must be edited strictly according to the protocol. Any illegal command will be discarded on the APP side and will not be executed.

Waveform Operation

When a third-party terminal wants to dispatch channel waveform data, it sends a specified JSON command.

Terminal sends waveform data downwards: {"type":"msg","clientId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","targetId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","message":"pulse-x:["xxxxxxxxxxxxxxxx","xxxxxxxxxxxxxxxx",......,"xxxxxxxxxxxxxxxx"]"}

The SOCKET service forwards the JSON to the APP according to the corresponding ID. When the APP receives data with type = msg, message = pulse-x:[], it executes the waveform output operation.

Command explanation:

  1. pulse-channel:[waveform data,waveform data,......,waveform data]
  2. Channel: A - A channel; B - B channel
  3. Data [waveform data,waveform data,......,waveform data]: The maximum length of the array is 100. If it exceeds the range, the APP will discard all data.
  4. Waveform data must be in 8-byte HEX (hexadecimal) format. For details on waveform data, please refer to the Bluetooth Protocol of Coyote Erotic Pulse Host V3.
  • Tips: Each piece of waveform data represents 100ms of data, so if 10 pieces of data are sent each time, that is 1s of data. Because the network has a certain delay, to ensure the continuity of waveform output, it is recommended that the interval for sending waveform data be slightly less than the time length of the waveform data (< 1s).
  • Tips: The maximum length of the array is 100, which means at most 10s of data can be placed. Additionally, the maximum length of the waveform queue in the APP is 500, which is 50s of data. If the subsequently received data cannot be entirely put into the waveform queue, the excess part will be discarded. So carefully consider your data length and data sending interval.

Clear Waveform Queue

The waveform execution in the APP is based on the waveform queue, following the first-in-first-out principle, and the queue can cache 500 pieces of waveform data (50s of data).

When there is still unexecuted waveform data in the waveform queue, and the third-party terminal wishes to immediately execute new waveform data, it needs to first execute a clear operation on the corresponding channel's waveform queue, and then send the waveform data to fulfill the requirement of immediately executing the new waveform data.

Terminal sends data downwards to clear the waveform queue: {"type":"msg","clientId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","targetId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","message":"clear-x"}

The SOCKET service forwards the JSON to the APP according to the corresponding ID. When the APP receives data with type = msg, message = clear-x, it executes the specified channel waveform queue clear operation.

Command explanation:

  1. clear-channel
  2. Channel: 1 - A channel; 2 - B channel
  • Tips: It is recommended that after the clear waveform queue command is dispatched, a time interval should be set before dispatching new waveform data. This prevents the situation where the clear queue command is executed later than the waveform data due to network fluctuations, etc., resulting in the loss of waveform data.

APP Feedback

There are several icon buttons of different shapes in the APP. Clicking them can send the command of the currently pressed button upwards. The third-party terminal can draft the sensory states represented by icons of different shapes.

APP sends intensity data upwards: {"type":"msg","clientId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","targetId":"xxxx-xxxxxxxxx-xxxxx-xxxxx-xx","message":"feedback-x"}

SOCKET forwards the JSON to the third-party terminal according to the corresponding ID. When the terminal receives data with type = msg, message = feedback-x, it updates the UI (displaying the feedback from the APP user).

Command explanation:

  1. feedback-index
  2. index: The subscripts for the 5 buttons of A channel (from left to right) are: 0, 1, 2, 3, 4; the subscripts for the 5 buttons of B channel (from left to right) are: 5, 6, 7, 8, 9.
  • Tips: You can freely draft what each shape represents in terms of APP user feedback in your self-developed terminal.

Front-end Protocol (Important)

If you wish to develop your own front-end but entirely use our back-end code, then your front-end protocol will be somewhat different from the above.

Please note: Messages from the front-end protocol cannot be sent directly to the app, which will result in failure to parse. For the messages actually received by the App, please see the APP receiving protocol content explanation in the first half.

  1. Intensity Operation:

    type : 1 -> channel intensity decrease; 2 -> channel intensity increase; 3 -> channel intensity returns to zero; 4 -> channel intensity is specified to a certain value

    strength: amount of intensity change/specified intensity value (when type is 1 or 2, this value will be forcibly set to 1)

    message: 'set channel' fixed unchanged

    channel: 1 -> A channel; 2 -> B channel

    clientId: Terminal ID

    targetId: APP ID

    A channel intensity minus 5 : { type : 1, strength: 5, message : 'set channel', channel: 1, clientId: xxxx-xxxxxxxxx-xxxxx-xxxxx-xx, targetId: xxxx-xxxxxxxxx-xxxxx-xxxxx-xx }

    B channel intensity plus 1 : { type : 2, strength: 1, message : 'set channel', channel: 2, clientId: xxxx-xxxxxxxxx-xxxxx-xxxxx-xx, targetId: xxxx-xxxxxxxxx-xxxxx-xxxxx-xx }

    B channel intensity becomes 0 : { type : 3, strength: 0, message : 'set channel', channel: 2, clientId: xxxx-xxxxxxxxx-xxxxx-xxxxx-xx, targetId: xxxx-xxxxxxxxx-xxxxx-xxxxx-xx }

    B channel intensity becomes 10 : { type : 4, strength: 10, message : 'set channel', channel: 2, clientId: xxxx-xxxxxxxxx-xxxxx-xxxxx-xx, targetId: xxxx-xxxxxxxxx-xxxxx-xxxxx-xx }

  2. Waveform Data:

    In the back-end code, the default waveform data sending interval is 200ms. You can adjust the back-end waveform data sending interval according to your waveform data (modify the variable value of timeSpace in the back-end code).

    type : clientMsg fixed unchanged

    message : A channel waveform data (hexadecimal HEX array JSON, see the protocol description above for details)

    message2 : B channel waveform data (hexadecimal HEX array JSON, see the protocol description above for details)

    time1 : duration of continuous sending of A channel waveform data

    time2 : duration of continuous sending of B channel waveform data

    clientId: Terminal ID

    targetId: APP ID

  3. Clear Waveform Queue:

    type : msg fixed unchanged

    message: clear-1 -> clear A channel waveform queue; clear-2 -> clear B channel waveform queue

    clientId: Terminal ID

    targetId: APP ID

Terminal QR Code

The QR code of the third-party terminal must be generated in the manner specified by the protocol, otherwise, the APP will not be able to recognise the QR code.

The third-party terminal needs to first connect to the SOCKET service, receive the terminal ID returned by the service, and store it.

The QR code content is: https://www.dungeon-lab.com/app-download.php#DGLAB-SOCKET#xxxxxxxxx

Content explanation:

  1. The QR code must contain our APP official website download address: https://www.dungeon-lab.com/app-download.php

  2. The QR code must contain the tag: DGLAB-SOCKET

  3. The QR code must contain the SOCKET service address and contain the terminal ID information, and there must be no other content between the service address and the ID information.

    Examples:

    1. Correct -> wss://ws.dungeon-lab.cn/xxxx-xxxxxxxxx-xxxxx-xxxxx-xx
    2. Incorrect -> wss://ws.dungeon-lab.cn/xxxx/xxxx-xxxxxxxxx-xxxxx-xxxxx-xx
  4. The QR code has and only has two # to separate the contents mentioned in 1, 2, and 3, otherwise, the APP will not be able to recognise the content.

  5. Except for the necessary content described above, the QR code must not involve any other content, otherwise, the APP may not be able to recognise it.

Error Codes

200 - Success

209 - The other client has disconnected

210 - No valid clientID in the QR code

211 - Socket is connected, but the server is delaying in dispatching the app's id for binding

400 - This id has already been bound by another client

401 - The target client to be bound does not exist

402 - The recipient and the sender are not in a binding relationship

403 - The content sent is not a standard JSON object

404 - Recipient not found (offline)

405 - The length of the dispatched message is greater than 1950

500 - Server internal exception

If you have any questions, please consult service@dungeon-lab.com or raise issues