deno上で動作するデスクトップアプリを数種類作成して、必要に応じて起動させたり終了させたりしたい関係で、TCP接続に使えるポート番号を探すサンプルを先日作成しましたが、意図した通りの動作になっていませんでした。
具体的には、使用中のポート番号でのサーバ起動をトライしたタイミングでエラーが発生してしまうという状態でした。
上記の問題を解消したバージョンのサンプルが以下。
具体的には、使用中のポート番号でのサーバ起動をトライしたタイミングでエラーが発生してしまうという状態でした。
上記の問題を解消したバージョンのサンプルが以下。
他のプロセスで使用されているポート番号でのサーバ起動をトライすると、以下のように表示されます。
「try」で囲んでいるため、エラーが発生した場合は「catch{ ~ }」が実行されると思っていましたが、そのようには動作しませんでした。
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 { serve } from "https://deno.land/std@0.86.0/http/server.ts"; | |
async function サーバ起動後(サーバ: any){ | |
for await (const request of サーバ) { | |
let bodyContent = "Your user-agent is:\n\n"; | |
bodyContent += request.headers.get("user-agent") || "Unknown"; | |
request.respond({ status: 200, body: bodyContent }); | |
} | |
} | |
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) | |
break | |
} | |
catch(e){} | |
} |
仕方がないので、以下のようにしました。
- netstatコマンドを使って使用中のポート番号のリストを得る。
- findコマンドを使って上記のリストから、任意のポート番号を含む行を抽出する。
- 上記を行うバッチファイルを作成する。
- Deno.runで上記バッチファイルを実行して、標準出力を解釈してポート番号が使用中か否かを判定する。
上記赤字の問題については後日、別の投稿を作成します。
修正版のソースが以下。
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 { serve } from "https://deno.land/std@0.86.0/http/server.ts"; | |
async function 空いてるport番号を返す(): Promise<number>{ | |
let pathBat = await 一時ファイルを作成('netstat -na | find "%~1"') | |
if(pathBat.match(/[ ]/)){ | |
throw new Error('一時ファイルのPathにスペースが含まれています。\n'+pathBat+'\nDeno.runでは「"」の記号の前に「\\」が挿入されてしまうため、使用できません。') | |
} | |
for(let port=49152; port<=65535 ;port++){ | |
const p = Deno.run({cmd:['cmd', '/C', 'chcp 65001 & '+pathBat+' ' + port], stdout:'piped'}) | |
const o = await p.output() | |
const text = new TextDecoder().decode(o) | |
console.log('text:\n'+text) | |
if(text.indexOf(':'+port)==-1){ | |
Deno.remove(pathBat) | |
return port | |
} | |
} | |
throw new Error('throw from port num search') | |
} | |
async function 一時ファイルを作成(value:string){ | |
const path = await Deno.makeTempFile({prefix: 'deno_tmp', suffix:'.bat'}) | |
await Deno.writeTextFile(path, value) | |
return path | |
} | |
async function ブラウザからのリクエストに対応開始する(サーバ: any){ | |
for await (const request of サーバ) { | |
let bodyContent = "Your user-agent is:\n\n"; | |
bodyContent += request.headers.get("user-agent") || "Unknown"; | |
request.respond({ status: 200, body: bodyContent }); | |
} | |
} | |
function ブラウザ起動(port: number){ | |
Deno.run({cmd:['cmd', '/C start http://localhost:'+port]}) | |
} | |
const port = await 空いてるport番号を返す() | |
const server = serve({ hostname: "0.0.0.0", port: port }) | |
console.log(`HTTP webserver running. Access it at: http://localhost:` + port + `/`) | |
ブラウザからのリクエストに対応開始する(server) | |
ブラウザ起動(port) |
修正版の実行結果。
49152~49153が使用中の状況で上記のサンプルを実行すると、以下のようになりますので、意図した通りの動作になっている事が確認できました。
うまくいくケースだけじゃなく、失敗する筈のケースも動作確認するべき…とは思っているのですが、忘れがちです…。反省。
0 件のコメント:
コメントを投稿