Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@robojs/sync - useSyncBroadcast and useSyncContext hooks #329

Open
Pkmmte opened this issue Oct 21, 2024 — with Volta.net · 2 comments
Open

@robojs/sync - useSyncBroadcast and useSyncContext hooks #329

Pkmmte opened this issue Oct 21, 2024 — with Volta.net · 2 comments
Labels

Comments

Copy link
Member

Pkmmte commented Oct 21, 2024

Points: 5


These new hooks are intended to bring about a new Context System.

Essentially, each namespace (dependency array) may have a context, not just state. It can be used to listen to client events connected to the same key. Since we'd have all clients in the same context, that would also allow us to broadcast arbitrary payloads.

Context System

The existing useSyncState would be modified to return a third variable:

const [status, setStatus, statusContext ] = useSyncState('winning', ['status'])

The statusContext object would include the following fields:

  • clients: An array of active clients connected with the same dependency array.
  • clientId: The unique identifier for the current client.
  • isHost: A boolean indicating if the current client is the host or initiator.
  • metadata: Any additional metadata associated with the synchronization context.
  • on: Function to register event handlers.

Proposed type signature:

interface SyncContext<ClientData = unknown> {
  clients: Client<ClientData>[]
  clientId: string
  isHost: boolean
  metadata?: Record<string, unknown>
  on?: (event: string, (client: Client<ClientData>) => void) => void
}

interface Client<ClientData = any> {
  id: string
  data?: ClientData // e.g., user info
}

Example usage:

import { useSyncState } from '@robojs/sync'

export function MultiplayerGame() {
  const [gameState, setGameState, syncContext] = useSyncState(initialGameState, ['gameRoom'])
  const { clients, clientId, isHost, broadcast } = syncContext

  // Use the context to implement custom logic
  useEffect(() => {
    if (isHost) {
      // Perform host-specific initialization
    }
  }, [isHost])

  const handlePlayerAction = (action) => {
    // Update the game state locally
    setGameState((prev) => ({ ...prev, ...action }))

    // Broadcast the action to other clients
    broadcast(action)
  }

  return (
    <div>
      <GameBoard state={gameState} onAction={handlePlayerAction} />
      <div>Connected Players: {clients.length}</div>
    </div>
  )
}

useSyncBroadcast

This new hook would allow receiving and sending direct broadcasts to other clients in the same dependency array, or both.

It returns a context object and accepts a function as the first argument. The callback receives the payload and context as arguments. Think of it as a useEffect without the boilerplate.

const { broadcast, context, send } = useSyncBroadcast((message: string, context) => {
  console.log(context.client.id, 'said', message)
}, ['status'])

Result object includes:

  • broadcast: A function to send messages or updates to all connected clients.
  • context: The context for the dependency array.
  • send: A function to send a message or update to a specific client.

useSyncContext

Can be used to get the context of a dependency array easily.

const context = useSyncContext(['status'])

It can optionally accept an object as an optional first item for convenience callbacks:

useSyncContext({
  onConnect: (client) => console.log(client.id, ‘has left’),
  onDisconnect: (client) => console.log(client.id, ‘has joined’)
}, [‘status’])
@Pkmmte Pkmmte changed the title @robojs/sync - useSyncContext and useSyncBroadcast hooks @robojs/sync - useSyncBroadcast and useSyncContext hooks Oct 21, 2024
@Pkmmte Pkmmte added enhancement New feature or request good first issue Good for newcomers plugin hacktoberfest labels Oct 21, 2024 — with Volta.net
@Rishi-0007
Copy link

Hi @Pkmmte,

I’d love to work on this issue. Could you please assign it to me? As I’m new to this repository, I’d also appreciate any guidance to help me get started.

@Pkmmte Pkmmte removed the good first issue Good for newcomers label Oct 25, 2024
@Pkmmte
Copy link
Member Author

Pkmmte commented Oct 25, 2024

Hi @Rishi-0007

Thank you for your interest in contributing to Robo! This issue was initially tagged as a good first issue, but we then found it involves some deeper integrations that might be challenging as an initial task. In particular due to the way our server and core framework interact with this plugin's websocket connections.

I recommend looking at issue #331 instead, which could be a great place to start. It's more tailored to new contributors and should help you get acquainted with our codebase. I’ve added more details on the exact file to modify and am here (and on Discord) to provide any guidance you need to get started.

Feel free to ask any questions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants