@platform/socket¶
Location: modules/platform/socket/
Dependencies: @platform/core
Overview¶
@platform/socket provides the WebSocket transport layer of the platform using Socket.io. It handles:
- Setting up the Socket.io server on the Express http server.
- The
ServerServiceregistry — a central map of services that can be called over the socket. - The client-side
SocketContext— connects a Socket.io client instance and exposes it to React components. - The
useServicehook — a Proxy-based RPC client that calls server services transparently.
Note: The pub/sub layer (publications, subscriptions,
SubscriptionContext) lives in@platform/schema, not in this module.
Contexts¶
| Context | Entry point | Contents |
|---|---|---|
client |
src/client/index.ts |
SocketContext, useSocketContext, useService |
server |
src/server/index.ts |
SocketServerModule, ServerService |
common |
src/common/index.ts |
Service type |
Common API¶
| Export | Description |
|---|---|
Service<Name> |
Base interface for a named service: { name: Name }. Services extend this and add methods. |
Server API¶
SocketServerModule¶
Attaches Socket.io to the Express http.Server from ServerExpressService. Listens for incoming 'service' events and delegates to ServerService.handleServiceCall.
The socket protocol for RPC calls is:
Client → Server: socket.emit('service', name, method, args[])
Server → Client: callback({ result }) or callback({ __error: CoreError })
ServerService¶
The central service registry on the server.
| Method | Signature | Description |
|---|---|---|
register(name, service) |
(name: string, service: Service) => void |
Register a service implementation by name |
get(name) |
(name: string) => Service |
Retrieve a registered service |
handleServiceCall(name, method, args, socket, callback) |
— | Dispatches an incoming socket call to the correct service method |
import { ServerService } from '@platform/socket/server'
const myService = {
name: 'myModule',
getData: async (id: string) => {
return await MyRepository.findById(id)
}
}
ServerService.register('myModule', myService)
Client API¶
SocketContext¶
React context provider that creates and manages the Socket.io client connection.
// Wrap your app (already done by Application in @platform/core)
<SocketContext>
<App />
</SocketContext>
useSocketContext¶
| Field | Type | Description |
|---|---|---|
socket |
Socket |
The Socket.io client instance |
connected |
boolean |
Whether the socket is currently connected |
useService¶
Proxy-based RPC hook. Returns a service object whose methods call the matching server service method over the socket.
import { useService } from '@platform/socket/client'
import type { MyService } from '@myModule/common'
function MyComponent() {
const myService = useService<MyService>('myModule')
const handleClick = async () => {
const data = await myService.getData('123')
console.log(data)
}
}
Errors thrown by the server (wrapped in CoreError) are re-thrown on the client.
Usage Example¶
// Server — define and register a service
import { ServerService } from '@platform/socket/server'
import type { Service } from '@platform/socket/common'
type NoteService = Service<'notes'> & {
getAll(): Promise<Note[]>
create(note: Omit<Note, '_id'>): Promise<Note>
}
const noteService: NoteService = {
name: 'notes',
getAll: async () => NoteRepo.findAll(),
create: async (note) => NoteRepo.insert(note)
}
ServerService.register('notes', noteService)
// Client — call the service
import { useService } from '@platform/socket/client'
function NoteList() {
const noteService = useService<NoteService>('notes')
const [notes, setNotes] = useState<Note[]>([])
useEffect(() => {
noteService.getAll().then(setNotes)
}, [])
return <ul>{notes.map(n => <li key={n._id}>{n.title}</li>)}</ul>
}