Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/h3Public

Commit0e930ef

Browse files
authored
feat: websocket support (#671)
1 parent2d10070 commit0e930ef

File tree

16 files changed

+359
-21
lines changed

16 files changed

+359
-21
lines changed

‎.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ dist
22
lib
33
.nuxt
44
.output
5+
docs/**/*.md

‎docs/.config/docs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description:
77
github:unjs/h3
88
themeColor:amber
99
url:https://h3.unjs.io
10-
#automd: true # HMR seems unstable
10+
automd:true
1111
redirects:{}
1212
landing:
1313
heroLinks:

‎docs/1.guide/6.websocket.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
icon:cib:socket-io
3+
---
4+
5+
#WebSockets
6+
7+
>H3 has built-in support for cross platform WebSocket and SSE.
8+
9+
H3 natively supports runtime agnostic[WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) API using[CrossWS](https://crossws.unjs.io/).
10+
11+
::tip
12+
You can define WebSocket handlers in your exisiting[Event Handlers](/guide/event-handler) to define multiple websocket handlers, dynamically matched with your same route defenitions!
13+
::
14+
15+
:read-more{title="WebSocket in MDN"to="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket"}
16+
17+
:read-more{title="CrossWS"to="https://crossws.unjs.io/"}
18+
19+
>[!IMPORTANT]
20+
>WebSockets support is currently experimental and available in[nightly channel](/guide/nightly).
21+
22+
##Usage
23+
24+
###Example
25+
26+
>[!TIP]
27+
>Yuu can use`npx listhen --ws -w websocket.ts` to run this example
28+
29+
<!-- automd:file code src="../../examples/websocket.ts"-->
30+
31+
```ts [websocket.ts]
32+
import {createApp,defineEventHandler,defineWebSocketHandler }from"h3";
33+
34+
exportconst app=createApp();
35+
36+
app.use(
37+
defineEventHandler(()=>
38+
fetch(
39+
"https://raw.githubusercontent.com/unjs/crossws/main/examples/h3/public/index.html",
40+
).then((r)=>r.text()),
41+
),
42+
);
43+
44+
app.use(
45+
"/_ws",
46+
defineWebSocketHandler({
47+
open(peer) {
48+
console.log("[ws] open",peer);
49+
},
50+
51+
message(peer,message) {
52+
console.log("[ws] message",peer,message);
53+
if (message.text().includes("ping")) {
54+
peer.send("pong");
55+
}
56+
},
57+
58+
close(peer,event) {
59+
console.log("[ws] close",peer,event);
60+
},
61+
62+
error(peer,error) {
63+
console.log("[ws] error",peer,error);
64+
},
65+
}),
66+
);
67+
68+
```
69+
70+
<!-- /automd-->
71+
72+
##Server Sent Events (SSE)
73+
74+
As an alternative to WebSockets, you can use[Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events).
75+
76+
H3 has a built-in API to create server-sent events using`createEventStream(event)` utility.
77+
78+
>[!IMPORTANT]
79+
>SSE support is currently experimental and available in[nightly channel](/guide/nightly).
80+
81+
###Example
82+
83+
<!-- automd:file code src="../../examples/server-sent-events.ts"-->
84+
85+
```ts [server-sent-events.ts]
86+
import {createApp,createRouter,eventHandler,createEventStream }from"h3";
87+
88+
exportconst app=createApp();
89+
90+
const router=createRouter();
91+
app.use(router);
92+
93+
router.get(
94+
"/",
95+
eventHandler((event)=> {
96+
const eventStream=createEventStream(event);
97+
98+
// Send a message every second
99+
const interval=setInterval(async ()=> {
100+
awaiteventStream.push("Hello world");
101+
},1000);
102+
103+
// cleanup the interval and close the stream when the connection is terminated
104+
eventStream.onClosed(async ()=> {
105+
clearInterval(interval);
106+
awaiteventStream.close();
107+
});
108+
109+
returneventStream.send();
110+
}),
111+
);
112+
113+
```
114+
115+
<!-- /automd-->

‎docs/3.adapters/1.node.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,18 @@ Run this command to run your servers:
4545
```sh
4646
npx --yes listhen ./app.ts
4747
```
48+
49+
##WebSocket support
50+
51+
:read-more{to="https://crossws.unjs.io/adapters/node"}
52+
53+
>[!TIP]
54+
>When using listhen method, websocket is supported out of the box!
55+
56+
```ts
57+
importwsAdapterfrom"crossws/adapters/node";
58+
59+
const { handleUpgrade }=wsAdapter(app.websocket);
60+
61+
server.on("upgrade",handleUpgrade);
62+
```

‎docs/3.adapters/bun.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,27 @@ Now, your can run Bun server:
4040
```bash
4141
bun --bun ./server.mjs
4242
```
43+
44+
##WebSocket support
45+
46+
:read-more{to="https://crossws.unjs.io/adapters/bun"}
47+
48+
```ts
49+
importwsAdapterfrom"crossws/adapters/cloudflare";
50+
51+
const { websocket, handleUpgrade }=wsAdapter(app.websocket);
52+
53+
const handler=toWebHandler(app)
54+
55+
const server=Bun.serve({
56+
port:3000,
57+
websocket,
58+
fetch(req,server) {
59+
if (awaithandleUpgrade(req,server)) {
60+
return;
61+
}
62+
returnhandler(req)
63+
}
64+
});
65+
```
66+

‎docs/3.adapters/cloudflare.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,27 @@ To deploy, use `wrangler deploy`:
5757
npx wrangler deploy
5858
```
5959

60+
##WebSocket support
61+
62+
:read-more{to="https://crossws.unjs.io/adapters/cloudflare"}
63+
64+
```ts
65+
importwsAdapterfrom"crossws/adapters/cloudflare";
66+
67+
const { handleUpgrade }=wsAdapter(app.websocket);
68+
69+
exportdefault {
70+
async fetch(request,env,ctx) {
71+
if (request.headers.get("upgrade")==="websocket") {
72+
returnhandleUpgrade(request,env,context);
73+
}
74+
returnhandler(request, {
75+
cloudflare: {env,ctx },
76+
});
77+
},
78+
};
79+
```
80+
6081
---
6182

6283
::read-more

‎docs/3.adapters/deno.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,25 @@ To deploy, use `deployctl deploy`:
5151
deployctl deploy --prod --exclude=node_modules --import-map=./import_map.json ./deno.mjs
5252
```
5353

54+
##WebSocket support
55+
56+
:read-more{to="https://crossws.unjs.io/adapters/deno"}
57+
58+
```ts
59+
importwsAdapterfrom"crossws/adapters/deno";
60+
61+
const handler=toWebHandler(app)
62+
63+
const { handleUpgrade }=wsAdapter(app.websocket);
64+
65+
Deno.serve(request=> {
66+
if (request.headers.get("upgrade")==="websocket") {
67+
returnhandleUpgrade(request);
68+
}
69+
returnhandler(request)
70+
})
71+
```
72+
5473
---
5574

5675
::read-more

‎docs/bun.lockb

0 Bytes
Binary file not shown.

‎examples/websocket.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import{createApp,defineEventHandler,defineWebSocketHandler}from"h3";
2+
3+
exportconstapp=createApp();
4+
5+
app.use(
6+
defineEventHandler(()=>
7+
fetch(
8+
"https://raw.githubusercontent.com/unjs/crossws/main/examples/h3/public/index.html",
9+
).then((r)=>r.text()),
10+
),
11+
);
12+
13+
app.use(
14+
"/_ws",
15+
defineWebSocketHandler({
16+
open(peer){
17+
console.log("[ws] open",peer);
18+
},
19+
20+
message(peer,message){
21+
console.log("[ws] message",peer,message);
22+
if(message.text().includes("ping")){
23+
peer.send("pong");
24+
}
25+
},
26+
27+
close(peer,event){
28+
console.log("[ws] close",peer,event);
29+
},
30+
31+
error(peer,error){
32+
console.log("[ws] error",peer,error);
33+
},
34+
}),
35+
);

‎package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
},
3333
"dependencies": {
3434
"cookie-es":"^1.0.0",
35+
"crossws":"^0.2.0",
3536
"defu":"^6.1.4",
3637
"destr":"^2.0.3",
3738
"iron-webcrypto":"^1.0.0",
@@ -56,7 +57,7 @@
5657
"express":"^4.18.2",
5758
"get-port":"^7.0.0",
5859
"jiti":"^1.21.0",
59-
"listhen":"^1.6.0",
60+
"listhen":"^1.7.2",
6061
"node-fetch-native":"^1.6.2",
6162
"prettier":"^3.2.5",
6263
"react":"^18.2.0",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp