ブラウザからローカルファイルを読み書きしたり各種コマンドを実行できるようにするためにブラウザとdenoの間で通信できるようにしたいです。
まずは接続するだけのソースが以下。
まずは接続するだけのソースが以下。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="ja"> | |
<head> | |
<meta charset="UTF-8" /> | |
<title>wawawa--</title> | |
<link rel="stylesheet" type="text/css" href="./css.css"> | |
</head> | |
<body> | |
<p class=greenText>wowowo--</p> | |
</body> | |
<script> | |
let ws | |
function ws接続(){ | |
if(ws){ ws.close() } | |
ws = new WebSocket(`ws://${location.host}/ws`) | |
} | |
ws接続() | |
</script> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// --allow-run --allow-net --allow-read | |
import { serve } from "https://deno.land/std@0.86.0/http/server.ts"; | |
import * as path from "https://deno.land/std@0.97.0/path/mod.ts"; // pathResolver | |
import { | |
acceptWebSocket, | |
acceptable, | |
WebSocket, | |
isWebSocketCloseEvent, | |
} from "https://deno.land/std/ws/mod.ts"; | |
function pathResolver(meta: ImportMeta): (p: string) => string { | |
return (p) => path.fromFileUrl(new URL(p, meta.url)) | |
} | |
const resolve = pathResolver(import.meta); | |
async function サーバ起動後(サーバ: any){ | |
for await (const request of サーバ) { | |
if(request.method != 'GET'){return} | |
アドレス毎(request) | |
} | |
} | |
async function アドレス毎(request: any){ | |
console.log('url:[' + request.url + ']') | |
let url = request.url | |
if(url=='/ws'){return webSocket接続(request)} | |
if(url=='/'){ url = './index.html' } | |
if(url.indexOf('/')==0){ url = '.' + url } | |
url = resolve(url) | |
const ファイルの有無 = await fileExists(url) | |
if(!ファイルの有無){ | |
return request.respond({ status: 404 }) | |
} | |
const file = await Deno.open(url); | |
request.respond({ | |
status: 200, | |
headers: new Headers({"content-type": 拡張子2contentType(url)}), | |
body: file | |
}); | |
} | |
function webSocket接続(request: any):void{ | |
console.log('webSocket接続') | |
if(!acceptable(request)){return console.log('webSocket接続 not acceptable')} | |
acceptWebSocket({ | |
conn: request.conn, | |
bufReader: request.r, | |
bufWriter: request.w, | |
headers: request.headers, | |
}).then(wsHandler); | |
} | |
const clients = new Map<number, WebSocket>(); | |
let clientId = 0; | |
async function wsHandler(ws: WebSocket): Promise<void> { | |
const id = ++clientId; | |
clients.set(id, ws); | |
dispatch(`[${id}]さんが入室しました`); | |
for await (const msg of ws) { | |
if (typeof msg === "string") { | |
dispatch(`[${id}] > ${msg}`); | |
} else if (isWebSocketCloseEvent(msg)) { | |
clients.delete(id); | |
dispatch(`[${id}]さんが退室しました`); | |
break; | |
} | |
} | |
} | |
function dispatch(msg: string): void { | |
for (const key of clients.keys()) { | |
let client = clients.get(key) | |
if(client==undefined){ | |
clients.delete(key) | |
continue | |
} | |
try{ client.send(msg) } | |
catch(e){ clients.delete(key) } // メッセージの送信に失敗した相手は切断済みと判断する。 | |
} | |
} | |
function 拡張子2contentType(url: string):string{ | |
if(url.match(/\.htm(l?)$/)){return 'text/html'} | |
if(url.match(/\.css$/)){return 'text/css'} | |
return '' | |
} | |
async function fileExists(filePath: string): Promise<boolean> { | |
try { | |
await Deno.lstat(filePath); | |
return true; | |
} catch (err) { | |
if (err instanceof Deno.errors.NotFound) { | |
return false; | |
} | |
throw err; | |
} | |
} | |
function ブラウザ起動(port: number){ | |
Deno.run({cmd:['cmd', '/C start http://localhost:'+port]}) | |
} | |
for(let port=49152; port<=65535 ;port++){ | |
try{ | |
const server = serve({ hostname: "0.0.0.0", port: port }); | |
console.log(`HTTP webserver running. Access it at: http://localhost:` + port + `/`); | |
サーバ起動後(server) | |
} | |
catch(e){continue} | |
ブラウザ起動(port) | |
break | |
} |
実行結果
webSocketに対応していないブラウザで開いた場合は上図のようになる。
edgeで開くと以下のようになる。
以下のページを参考にさせて頂きました。
Denoの標準ライブラリでチャットアプリを作ってみました🦕
WebSocketについて調べてみた。
webSocketに対応していないブラウザで開いた場合は上図のようになる。
edgeで開くと以下のようになる。
以下のページを参考にさせて頂きました。
Denoの標準ライブラリでチャットアプリを作ってみました🦕
WebSocketについて調べてみた。
0 件のコメント:
コメントを投稿