Sockets
ARO provides built-in TCP socket support for bidirectional real-time communication. This chapter covers socket servers and clients.
Socket Server
Starting a Server
Listen for TCP connections in Application-Start:
(Application-Start: Socket Server) {
Listen on port 9000 as <socket-server>.
Log "Socket server listening on port 9000" to the <console>.
Keepalive the <application> for the <events>.
Return an <OK: status> for the <startup>.
}
Connection Events
Socket servers emit events for connection lifecycle:
| Event | When Triggered |
|---|---|
ClientConnected | Client connects |
DataReceived | Data received from client |
ClientDisconnected | Client disconnects |
Handling Connections
(Handle Connection: ClientConnected Handler) {
Extract the <connection-id> from the <event: connectionId>.
Extract the <remote-address> from the <event: remoteAddress>.
Log "Client connected: ${remote-address}" to the <console>.
(* Send welcome message *)
Send the <welcome> to the <event: connection> with "Welcome to the server!".
Return an <OK: status> for the <connection>.
}
Receiving Data
(Handle Data: DataReceived Handler) {
Extract the <data> from the <event: data>.
Extract the <connection> from the <event: connection>.
Extract the <connection-id> from the <event: connectionId>.
Log "Received from ${connection-id}: ${data}" to the <console>.
(* Process the data *)
<Process> the <response> from the <data>.
(* Send response back *)
Send the <response> to the <connection>.
Return an <OK: status> for the <data>.
}
Handling Disconnections
(Handle Disconnect: ClientDisconnected Handler) {
Extract the <connection-id> from the <event: connectionId>.
Extract the <reason> from the <event: reason>.
Log "Client ${connection-id} disconnected: ${reason}" to the <console>.
(* Clean up client state *)
Delete the <client-state> from the <client-registry> where id = <connection-id>.
Return an <OK: status> for the <disconnect>.
}
Socket Client
Connecting to a Server
(Connect to Server: External Service) {
Connect to <host: "192.168.1.100"> on port 8080 as <server-connection>.
(* Send initial handshake *)
Send the <handshake> to the <server-connection> with { type: "hello", client: "my-app" }.
Return an <OK: status> for the <connection>.
}
Sending Data
(Send Message: Messaging) {
Create the <message> with {
type: "chat",
content: <content>,
timestamp: <current-time>
}.
Send the <message: JSON> to the <server-connection>.
Return an <OK: status> for the <send>.
}
Common Patterns
Echo Server
(Application-Start: Echo Server) {
Listen on port 9000 as <echo-server>.
Log "Echo server listening on port 9000" to the <console>.
Keepalive the <application> for the <events>.
Return an <OK: status> for the <startup>.
}
(Echo Data: DataReceived Handler) {
Extract the <data> from the <event: data>.
Extract the <connection> from the <event: connection>.
(* Echo back the received data *)
Send the <data> to the <connection>.
Return an <OK: status> for the <echo>.
}
Chat Server
(Application-Start: Chat Server) {
Listen on port 9000 as <chat-server>.
Create the <clients> with [].
Publish as <connected-clients> <clients>.
Keepalive the <application> for the <events>.
Return an <OK: status> for the <startup>.
}
(Register Client: ClientConnected Handler) {
Extract the <connection> from the <event: connection>.
Extract the <connection-id> from the <event: connectionId>.
(* Add to connected clients *)
Store the <connection> into the <connected-clients> with id <connection-id>.
(* Notify others *)
Broadcast the <announcement> to the <chat-server> with "User joined".
Return an <OK: status> for the <registration>.
}
(Broadcast Message: DataReceived Handler) {
Extract the <message> from the <event: data>.
Extract the <sender-id> from the <event: connectionId>.
Create the <broadcast> with {
from: <sender-id>,
message: <message>,
timestamp: <current-time>
}.
(* Send to all connected clients *)
Broadcast the <broadcast: JSON> to the <chat-server>.
Return an <OK: status> for the <broadcast>.
}
Data Formats
Text Data
Send the <text> to the <connection> with "Hello, World!".
JSON Data
Create the <message> with {
type: "update",
data: { value: 42 }
}.
Send the <message: JSON> to the <connection>.
Broadcasting
To All Clients
Broadcast the <message> to the <socket-server>.
To Specific Clients
(* Send to specific connection *)
Send the <message> to the <connection>.
(* Send to connection by ID *)
Retrieve the <client> from the <connected-clients> where id = <client-id>.
Send the <message> to the <client: connection>.
Best Practices
Validate Incoming Data
(Handle Data: DataReceived Handler) {
Extract the <raw-data> from the <event: data>.
(* Validate data format *)
Parse the <message: JSON> from the <raw-data>.
if <message> is empty then {
Log "Invalid message format" to the <console>.
Return an <OK: status> for the <validation>.
}
Validate the <message> for the <message-schema>.
(* Process valid message *)
<Process> the <result> from the <message>.
Return an <OK: status> for the <processing>.
}
Clean Up on Shutdown
(Application-End: Success) {
Log "Closing all connections..." to the <console>.
(* Notify all clients *)
Broadcast the <shutdown-notice> to the <socket-server> with "Server shutting down".
(* Close server *)
Close the <socket-server>.
Return an <OK: status> for the <shutdown>.
}
Next Steps
Events - Event-driven patterns
HTTP Services - HTTP communication
Application Lifecycle - Startup and shutdown