ブラウザに表示されたinputボックスにテキストファイルのPathを入力してボタンを押すと、内容がテキストエリアエレメントに表示される、というサンプルが以下。
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
// 動作確認したい機能だけをこのファイルにまとめる。 | |
import { | |
WebSocket, | |
isWebSocketCloseEvent, | |
} from "https://deno.land/std/ws/mod.ts"; | |
export async function wsHandler(ws: WebSocket): Promise<void> { | |
const id = ++clientId; | |
clients.set(id, ws); | |
console.log(`[${id}]さんが入室しました`); | |
for await (const msg of ws) { | |
if (typeof msg === "string") { | |
msg解釈(msg) | |
continue | |
} else if (isWebSocketCloseEvent(msg)) { | |
clients.delete(id); | |
dispatch(`[${id}]さんが退室しました`); | |
break; | |
} | |
} | |
} | |
// 以下はexportしない(import先からコールできない)関数など。 | |
async function msg解釈(msg:string): Promise<void> { | |
console.log('msg解釈['+msg+']') | |
const text = await テキストファイルを読み込む(msg) | |
dispatch(text) | |
} | |
async function テキストファイルを読み込む(path:string): Promise<string> { | |
const file = await Deno.open(path, {read: true}) | |
const data = await await Deno.readAll(file) | |
Deno.close(file.rid) | |
const text = new TextDecoder().decode(data) | |
return text | |
} | |
const clients = new Map<number, WebSocket>(); | |
let clientId = 0; | |
function dispatch(msg: string): void { | |
console.log('dispatch:'+msg) | |
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) | |
console.log('send err. key['+key+'] msg['+msg+']') | |
} | |
} | |
} |
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>test read</title> | |
<link rel="stylesheet" type="text/css" href="./css.css"> | |
</head> | |
<body> | |
Path:<input id=inpPath style="width:150px"> | |
<button id=btn>読込</button> | |
<textarea id=ta style="width:250px;height:100px"></textarea> | |
</body> | |
<script> | |
let ws | |
function ws接続(){ | |
if(ws){ ws.close() } | |
ws = new WebSocket(`ws://${location.host}/ws`) | |
ws.addEventListener("open", () => { | |
console.log('webSocket:open') | |
}); | |
ws.addEventListener("message", ({data}) => { | |
denoから受信(data) | |
}); | |
ws.addEventListener("close", () => { | |
console.log('webSocket:close') | |
}); | |
} | |
btn.onclick = function(){ | |
ws.send(inpPath.value) | |
} | |
function denoから受信(msg) { | |
ta.value = msg | |
} | |
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 { listenAndServe } from "https://deno.land/std/http/server.ts"; | |
import * as path from "https://deno.land/std@0.97.0/path/mod.ts"; // pathResolver | |
import { | |
acceptWebSocket, | |
acceptable, | |
} from "https://deno.land/std/ws/mod.ts"; | |
import { wsHandler } from './core.ts' | |
function 起動(): void{ | |
for(let port=49152; port<=65535 ;port++){ | |
try{ | |
const server = listenAndServe({ port: port }, async (req)=> { リクエスト処理(req) }); | |
console.log(`HTTP webserver running. Access it at: http://localhost:` + port + `/`); | |
} | |
catch(e){continue} | |
ブラウザ起動(port) | |
break | |
} | |
} | |
function ブラウザ起動(port: number){ | |
Deno.run({cmd:['cmd', '/C start http://localhost:'+port]}) | |
} | |
async function リクエスト処理(request: any){ | |
if(request.method != 'GET'){return} | |
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 拡張子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 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); | |
} | |
function pathResolver(meta: ImportMeta): (p: string) => string { | |
return (p) => path.fromFileUrl(new URL(p, meta.url)) | |
} | |
const resolve = pathResolver(import.meta); | |
起動() |
0 件のコメント:
コメントを投稿