mirror of
https://github.com/denoland/deno.git
synced 2025-01-22 06:09:25 -05:00
chore(std): remove std/ws connect method (#7403)
This commit is contained in:
parent
0d126930ca
commit
a3bcdb2b69
6 changed files with 18 additions and 194 deletions
|
@ -2,7 +2,6 @@
|
||||||
import { assert, assertEquals } from "../../testing/asserts.ts";
|
import { assert, assertEquals } from "../../testing/asserts.ts";
|
||||||
import { TextProtoReader } from "../../textproto/mod.ts";
|
import { TextProtoReader } from "../../textproto/mod.ts";
|
||||||
import { BufReader } from "../../io/bufio.ts";
|
import { BufReader } from "../../io/bufio.ts";
|
||||||
import { connectWebSocket, WebSocket } from "../../ws/mod.ts";
|
|
||||||
import { delay } from "../../async/delay.ts";
|
import { delay } from "../../async/delay.ts";
|
||||||
import { resolve, dirname, fromFileUrl } from "../../path/mod.ts";
|
import { resolve, dirname, fromFileUrl } from "../../path/mod.ts";
|
||||||
|
|
||||||
|
@ -57,18 +56,25 @@ Deno.test({
|
||||||
name: "[examples/chat] GET /ws should upgrade conn to ws",
|
name: "[examples/chat] GET /ws should upgrade conn to ws",
|
||||||
async fn() {
|
async fn() {
|
||||||
const server = await startServer();
|
const server = await startServer();
|
||||||
let ws: WebSocket | undefined;
|
let ws: WebSocket;
|
||||||
try {
|
try {
|
||||||
ws = await connectWebSocket("http://127.0.0.1:8080/ws");
|
ws = new WebSocket("ws://127.0.0.1:8080/ws");
|
||||||
const it = ws[Symbol.asyncIterator]();
|
await new Promise((resolve) => {
|
||||||
|
ws.onmessage = ((message) => {
|
||||||
assertEquals((await it.next()).value, "Connected: [1]");
|
assertEquals(message.data, "Connected: [1]");
|
||||||
ws.send("Hello");
|
ws.onmessage = ((message) => {
|
||||||
assertEquals((await it.next()).value, "[1]: Hello");
|
assertEquals(message.data, "[1]: Hello");
|
||||||
|
ws.close();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
ws.send("Hello");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
} finally {
|
} finally {
|
||||||
server.close();
|
server.close();
|
||||||
server.stdout.close();
|
server.stdout.close();
|
||||||
ws!.conn.close();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# ws
|
# ws
|
||||||
|
|
||||||
ws module is made to provide helpers to create WebSocket client/server.
|
ws module is made to provide helpers to create WebSocket server. For client
|
||||||
|
WebSockets, use the
|
||||||
|
[WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API).
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Server
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
import { serve } from "https://deno.land/std/http/server.ts";
|
import { serve } from "https://deno.land/std/http/server.ts";
|
||||||
|
@ -67,67 +67,6 @@ if (import.meta.main) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Client
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import {
|
|
||||||
connectWebSocket,
|
|
||||||
isWebSocketCloseEvent,
|
|
||||||
isWebSocketPingEvent,
|
|
||||||
isWebSocketPongEvent,
|
|
||||||
} from "https://deno.land/std/ws/mod.ts";
|
|
||||||
import { encode } from "https://deno.land/std/encoding/utf8.ts";
|
|
||||||
import { BufReader } from "https://deno.land/std/io/bufio.ts";
|
|
||||||
import { TextProtoReader } from "https://deno.land/std/textproto/mod.ts";
|
|
||||||
import { blue, green, red, yellow } from "https://deno.land/std/fmt/colors.ts";
|
|
||||||
|
|
||||||
const endpoint = Deno.args[0] || "ws://127.0.0.1:8080";
|
|
||||||
/** simple websocket cli */
|
|
||||||
try {
|
|
||||||
const sock = await connectWebSocket(endpoint);
|
|
||||||
console.log(green("ws connected! (type 'close' to quit)"));
|
|
||||||
|
|
||||||
const messages = async (): Promise<void> => {
|
|
||||||
for await (const msg of sock) {
|
|
||||||
if (typeof msg === "string") {
|
|
||||||
console.log(yellow(`< ${msg}`));
|
|
||||||
} else if (isWebSocketPingEvent(msg)) {
|
|
||||||
console.log(blue("< ping"));
|
|
||||||
} else if (isWebSocketPongEvent(msg)) {
|
|
||||||
console.log(blue("< pong"));
|
|
||||||
} else if (isWebSocketCloseEvent(msg)) {
|
|
||||||
console.log(red(`closed: code=${msg.code}, reason=${msg.reason}`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const cli = async (): Promise<void> => {
|
|
||||||
const tpr = new TextProtoReader(new BufReader(Deno.stdin));
|
|
||||||
while (true) {
|
|
||||||
await Deno.stdout.write(encode("> "));
|
|
||||||
const line = await tpr.readLine();
|
|
||||||
if (line === null || line === "close") {
|
|
||||||
break;
|
|
||||||
} else if (line === "ping") {
|
|
||||||
await sock.ping();
|
|
||||||
} else {
|
|
||||||
await sock.send(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
await Promise.race([messages(), cli()]).catch(console.error);
|
|
||||||
|
|
||||||
if (!sock.isClosed) {
|
|
||||||
await sock.close(1000).catch(console.error);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(red(`Could not connect to WebSocket: '${err}'`));
|
|
||||||
}
|
|
||||||
|
|
||||||
Deno.exit(0);
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
### isWebSocketCloseEvent
|
### isWebSocketCloseEvent
|
||||||
|
@ -173,9 +112,3 @@ Upgrade inputted TCP connection into WebSocket connection.
|
||||||
### createSecKey
|
### createSecKey
|
||||||
|
|
||||||
Returns base64 encoded 16 bytes string for Sec-WebSocket-Key header.
|
Returns base64 encoded 16 bytes string for Sec-WebSocket-Key header.
|
||||||
|
|
||||||
### connectWebSocket
|
|
||||||
|
|
||||||
Connect to WebSocket endpoint url with inputted endpoint string and headers.
|
|
||||||
|
|
||||||
- note: Endpoint must be acceptable for URL.
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
import {
|
|
||||||
connectWebSocket,
|
|
||||||
isWebSocketCloseEvent,
|
|
||||||
isWebSocketPingEvent,
|
|
||||||
isWebSocketPongEvent,
|
|
||||||
} from "./mod.ts";
|
|
||||||
import { encode } from "../encoding/utf8.ts";
|
|
||||||
import { BufReader } from "../io/bufio.ts";
|
|
||||||
import { TextProtoReader } from "../textproto/mod.ts";
|
|
||||||
import { blue, green, red, yellow } from "../fmt/colors.ts";
|
|
||||||
|
|
||||||
if (import.meta.main) {
|
|
||||||
const endpoint = Deno.args[0] || "ws://127.0.0.1:8080";
|
|
||||||
/** simple websocket cli */
|
|
||||||
try {
|
|
||||||
const sock = await connectWebSocket(endpoint);
|
|
||||||
console.log(green("ws connected! (type 'close' to quit)"));
|
|
||||||
|
|
||||||
const messages = async (): Promise<void> => {
|
|
||||||
for await (const msg of sock) {
|
|
||||||
if (typeof msg === "string") {
|
|
||||||
console.log(yellow(`< ${msg}`));
|
|
||||||
} else if (isWebSocketPingEvent(msg)) {
|
|
||||||
console.log(blue("< ping"));
|
|
||||||
} else if (isWebSocketPongEvent(msg)) {
|
|
||||||
console.log(blue("< pong"));
|
|
||||||
} else if (isWebSocketCloseEvent(msg)) {
|
|
||||||
console.log(red(`closed: code=${msg.code}, reason=${msg.reason}`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const cli = async (): Promise<void> => {
|
|
||||||
const tpr = new TextProtoReader(new BufReader(Deno.stdin));
|
|
||||||
while (true) {
|
|
||||||
await Deno.stdout.write(encode("> "));
|
|
||||||
const line = await tpr.readLine();
|
|
||||||
if (line === null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (line === "close") {
|
|
||||||
break;
|
|
||||||
} else if (line === "ping") {
|
|
||||||
await sock.ping();
|
|
||||||
} else {
|
|
||||||
await sock.send(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
await Promise.race([messages(), cli()]).catch(console.error);
|
|
||||||
|
|
||||||
if (!sock.isClosed) {
|
|
||||||
await sock.close(1000).catch(console.error);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(red(`Could not connect to WebSocket: '${err}'`));
|
|
||||||
}
|
|
||||||
|
|
||||||
Deno.exit(0);
|
|
||||||
}
|
|
|
@ -1,2 +1 @@
|
||||||
import "./example_client.ts";
|
|
||||||
import "./example_server.ts";
|
import "./example_server.ts";
|
||||||
|
|
|
@ -191,11 +191,6 @@ export async function readFrame(buf: BufReader): Promise<WebSocketFrame> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create client-to-server mask, random 32bit number
|
|
||||||
function createMask(): Uint8Array {
|
|
||||||
return crypto.getRandomValues(new Uint8Array(4));
|
|
||||||
}
|
|
||||||
|
|
||||||
class WebSocketImpl implements WebSocket {
|
class WebSocketImpl implements WebSocket {
|
||||||
readonly conn: Deno.Conn;
|
readonly conn: Deno.Conn;
|
||||||
private readonly mask?: Uint8Array;
|
private readonly mask?: Uint8Array;
|
||||||
|
@ -514,42 +509,6 @@ export async function handshake(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Connect to given websocket endpoint url.
|
|
||||||
* Endpoint must be acceptable for URL.
|
|
||||||
*/
|
|
||||||
export async function connectWebSocket(
|
|
||||||
endpoint: string,
|
|
||||||
headers: Headers = new Headers(),
|
|
||||||
): Promise<WebSocket> {
|
|
||||||
const url = new URL(endpoint);
|
|
||||||
const { hostname } = url;
|
|
||||||
let conn: Deno.Conn;
|
|
||||||
if (url.protocol === "http:" || url.protocol === "ws:") {
|
|
||||||
const port = parseInt(url.port || "80");
|
|
||||||
conn = await Deno.connect({ hostname, port });
|
|
||||||
} else if (url.protocol === "https:" || url.protocol === "wss:") {
|
|
||||||
const port = parseInt(url.port || "443");
|
|
||||||
conn = await Deno.connectTls({ hostname, port });
|
|
||||||
} else {
|
|
||||||
throw new Error("ws: unsupported protocol: " + url.protocol);
|
|
||||||
}
|
|
||||||
const bufWriter = new BufWriter(conn);
|
|
||||||
const bufReader = new BufReader(conn);
|
|
||||||
try {
|
|
||||||
await handshake(url, headers, bufReader, bufWriter);
|
|
||||||
} catch (err) {
|
|
||||||
conn.close();
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return new WebSocketImpl({
|
|
||||||
conn,
|
|
||||||
bufWriter,
|
|
||||||
bufReader,
|
|
||||||
mask: createMask(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createWebSocket(params: {
|
export function createWebSocket(params: {
|
||||||
conn: Deno.Conn;
|
conn: Deno.Conn;
|
||||||
bufWriter?: BufWriter;
|
bufWriter?: BufWriter;
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { TextProtoReader } from "../textproto/mod.ts";
|
||||||
import * as bytes from "../bytes/mod.ts";
|
import * as bytes from "../bytes/mod.ts";
|
||||||
import {
|
import {
|
||||||
acceptable,
|
acceptable,
|
||||||
connectWebSocket,
|
|
||||||
createSecAccept,
|
createSecAccept,
|
||||||
createSecKey,
|
createSecKey,
|
||||||
handshake,
|
handshake,
|
||||||
|
@ -194,17 +193,6 @@ Deno.test("[ws] acceptable should return false when headers invalid", () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test(
|
|
||||||
"[ws] connectWebSocket should throw invalid scheme of url",
|
|
||||||
async (): Promise<void> => {
|
|
||||||
await assertThrowsAsync(
|
|
||||||
async (): Promise<void> => {
|
|
||||||
await connectWebSocket("file://hoge/hoge");
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Deno.test("[ws] write and read masked frame", async () => {
|
Deno.test("[ws] write and read masked frame", async () => {
|
||||||
const mask = new Uint8Array([0, 1, 2, 3]);
|
const mask = new Uint8Array([0, 1, 2, 3]);
|
||||||
const msg = "hello";
|
const msg = "hello";
|
||||||
|
|
Loading…
Add table
Reference in a new issue