docs: update ef websocket codesample (#30846)

update code sample.
This commit is contained in:
Thor 雷神 Schaeff authored and GitHub committed 2024-12-04 13:23:18 +08:00
1 parent 1c3c3e9229
commit e58f2edde2
2 files changed
+12 -89

No files matched your search

@@ -7,7 +7,7 @@ subtitle: 'How to handle WebSocket connections in Edge Functions'
Edge Functions supports hosting WebSocket servers that can facilitate bi-directional communications with browser clients.
You can also establish outgoing WebSocket client connections to another server from Edge Functions (e.g., [OpenAI Realtime API](https://platform.openai.com/docs/guides/realtime/overview)).
You can also establish outgoing WebSocket client connections to another server from Edge Functions (e.g., [OpenAI Realtime API](https://platform.openai.com/docs/guides/realtime/overview)). You can find an example OpenAI Realtime Relay Server implementation on the [supabase-community GitHub account](https://github.com/supabase-community/openai-realtime-console?tab=readme-ov-file#using-supabase-edge-functions-as-a-relay-server).
### Writing a WebSocket server
@@ -92,94 +92,17 @@ server.listen(8080);
You can also establish an outbound WebSocket connection to another server from an Edge Function.
Combining it with incoming WebSocket servers, it's possible to use Edge Functions as a WebSocket proxy.
Combining it with incoming WebSocket servers, it's possible to use Edge Functions as a WebSocket proxy, for example as a [relay server](https://github.com/supabase-community/openai-realtime-console?tab=readme-ov-file#using-supabase-edge-functions-as-a-relay-server) for the [OpenAI Realtime API](https://platform.openai.com/docs/guides/realtime/overview).
Here is an example of proxying messages to OpenAI Realtime API.
We use [Supabase Auth](/docs/guides/functions/auth#fetching-the-user) to authenticate the user who is sending the messages.
```ts
import { createClient } from 'jsr:@supabase/supabase-js@2'
const supabase = createClient(
Deno.env.get('SUPABASE_URL'),
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')
)
const OPENAI_API_KEY = Deno.env.get('OPENAI_API_KEY')
Deno.serve(async (req) => {
const upgrade = req.headers.get('upgrade') || ''
if (upgrade.toLowerCase() != 'websocket') {
return new Response("request isn't trying to upgrade to websocket.")
}
// WebSocket browser clients does not support sending custom headers.
// We have to use the URL query params to provide user's JWT.
// Please be aware query params may be logged in some logging systems.
const url = new URL(req.url)
const jwt = url.searchParams.get('jwt')
if (!jwt) {
console.error('Auth token not provided')
return new Response('Auth token not provided', { status: 403 })
}
const { error, data } = await supabase.auth.getUser(jwt)
if (error) {
console.error(error)
return new Response('Invalid token provided', { status: 403 })
}
if (!data.user) {
console.error('user is not authenticated')
return new Response('User is not authenticated', { status: 403 })
}
const { socket, response } = Deno.upgradeWebSocket(req)
socket.onopen = () => {
// initiate an outbound WS connection with OpenAI
const url = 'wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01'
// openai-insecure-api-key isn't a problem since this code runs in an Edge Function (not client browser)
const openaiWS = new WebSocket(url, [
'realtime',
`openai-insecure-api-key.${OPENAI_API_KEY}`,
'openai-beta.realtime-v1',
])
openaiWS.onopen = () => {
console.log('Connected to OpenAI server.')
socket.onmessage = (e) => {
console.log('socket message:', e.data)
// only send the message if openAI ws is open
if (openaiWS.readyState === 1) {
openaiWS.send(e.data)
} else {
socket.send(
JSON.stringify({
type: 'error',
msg: 'openAI connection not ready',
})
)
}
}
}
openaiWS.onmessage = (e) => {
console.log(e.data)
socket.send(e.data)
}
openaiWS.onerror = (e) => console.log('OpenAI error: ', e.message)
openaiWS.onclose = (e) => console.log('OpenAI session closed')
}
socket.onerror = (e) => console.log('socket errored:', e.message)
socket.onclose = () => console.log('socket closed')
return response // 101 (Switching Protocols)
})
```
<$CodeSample
external={true}
org="supabase-community"
repo="openai-realtime-console"
commit="0f93657a71670704fbf77c48cf54d6c9eb956698"
path="/supabase/functions/relay/index.ts"
meta="supabase/functions/relay/index.ts"
lines={[[1, 3], [5, -1]]}
/>
### Authentication
+1 -1
View File
@@ -48,7 +48,7 @@ import { z, type SafeParseError } from 'zod'
import { fetchWithNextOptions } from '~/features/helpers.fetch'
import { EXAMPLES_DIRECTORY } from '~/lib/docs'
const ALLOW_LISTED_GITHUB_ORGS = ['supabase'] as [string, ...string[]]
const ALLOW_LISTED_GITHUB_ORGS = ['supabase', 'supabase-community'] as [string, ...string[]]
const linesSchema = z.array(z.tuple([z.coerce.number(), z.coerce.number()]))
const linesValidator = z