Trouble Connecting Server to Client with @effect/rpc Socket in TypeScript Project
Hello, I am trying to use @effect/rcp in my project but I am unable to connect via socket from server to Client. I spend like 2 hours on trying to make it work. What am I missing?
Here is the minimal example:
Here is the minimal example:
// Rcps.ts
import {Rpc, RpcGroup} from '@effect/rpc'
import {Schema} from 'effect'
export class Rcps extends RpcGroup.make(
Rpc.make('Test', {
success: Schema.String,
})
) {}
// rcpServer.ts
import {NodeHttpServer, NodeRuntime} from '@effect/platform-node/index'
import {HttpLayerRouter} from '@effect/platform/index'
import {RpcSerialization, RpcServer} from '@effect/rpc'
import {Effect, Layer} from 'effect'
import {createServer} from 'http'
import {Rcps} from './Rcps'
export const RcpHandlers = Rcps.toLayer(
Effect.gen(function* () {
return {
Test: () => Effect.succeed('ok'),
}
})
)
const RcpRouter = RpcServer.layerHttpRouter({
group: Rcps,
path: '/rcp',
}).pipe(Layer.provide(RcpHandlers), Layer.provide(RpcSerialization.layerJson))
const Main = HttpLayerRouter.serve(RcpRouter).pipe(
Layer.provide(NodeHttpServer.layer(createServer, {port: 3000}))
)
NodeRuntime.runMain(Layer.launch(Main))
// rcpClient.ts
import {Socket} from '@effect/platform'
import {NodeRuntime} from '@effect/platform-node/index'
import {RpcClient, RpcSerialization} from '@effect/rpc'
import {Effect, Layer} from 'effect'
import {Rcps} from './Rcps.js'
const ProtocoSocketLive = RpcClient.layerProtocolSocket({
retryTransientErrors: true,
}).pipe(
Layer.provide([
Socket.layerWebSocket('http://localhost:3000/rcp').pipe(
Layer.provide(Socket.layerWebSocketConstructorGlobal)
),
RpcSerialization.layerJson,
])
)
const program = Effect.gen(function* (_) {
const client = yield* RpcClient.make(Rcps)
const response = yield* _(client.Test())
console.log('Response from server:', response)
}).pipe(Effect.scoped)
program.pipe(Effect.provide(ProtocoSocketLive), NodeRuntime.runMain)// Rcps.ts
import {Rpc, RpcGroup} from '@effect/rpc'
import {Schema} from 'effect'
export class Rcps extends RpcGroup.make(
Rpc.make('Test', {
success: Schema.String,
})
) {}
// rcpServer.ts
import {NodeHttpServer, NodeRuntime} from '@effect/platform-node/index'
import {HttpLayerRouter} from '@effect/platform/index'
import {RpcSerialization, RpcServer} from '@effect/rpc'
import {Effect, Layer} from 'effect'
import {createServer} from 'http'
import {Rcps} from './Rcps'
export const RcpHandlers = Rcps.toLayer(
Effect.gen(function* () {
return {
Test: () => Effect.succeed('ok'),
}
})
)
const RcpRouter = RpcServer.layerHttpRouter({
group: Rcps,
path: '/rcp',
}).pipe(Layer.provide(RcpHandlers), Layer.provide(RpcSerialization.layerJson))
const Main = HttpLayerRouter.serve(RcpRouter).pipe(
Layer.provide(NodeHttpServer.layer(createServer, {port: 3000}))
)
NodeRuntime.runMain(Layer.launch(Main))
// rcpClient.ts
import {Socket} from '@effect/platform'
import {NodeRuntime} from '@effect/platform-node/index'
import {RpcClient, RpcSerialization} from '@effect/rpc'
import {Effect, Layer} from 'effect'
import {Rcps} from './Rcps.js'
const ProtocoSocketLive = RpcClient.layerProtocolSocket({
retryTransientErrors: true,
}).pipe(
Layer.provide([
Socket.layerWebSocket('http://localhost:3000/rcp').pipe(
Layer.provide(Socket.layerWebSocketConstructorGlobal)
),
RpcSerialization.layerJson,
])
)
const program = Effect.gen(function* (_) {
const client = yield* RpcClient.make(Rcps)
const response = yield* _(client.Test())
console.log('Response from server:', response)
}).pipe(Effect.scoped)
program.pipe(Effect.provide(ProtocoSocketLive), NodeRuntime.runMain)