これの続きでございます
Godotの資材をアップロードすれば行けるっしょ?
とりあえずPythonでWebSocketのバックエンドをコーディングをして、GodotのWebSocketPeerとの接続が成功すればあとはHTTPSのHTML置き場にアップロードすればチョチョイのパーっしょ。
そう思っていた時期が私にもありました。
とりあえずバックエンド
Python3でWebSocketのサーバーサイドのエコーバックを作る。
ポート番号に深い意味はない。
# coding: utf-8
import asyncio
import websockets
class WebSocketServer:
def __init__(self, host, port):
self.host = host
self.port = port
async def server(self, ws, path):
try:
async for msg in ws:
print(f"msg from client: {msg}")
print(f"Got your messaget: {msg}")
await ws.send(msg)
except Exception as e:
print(e)
async def start(self):
async with websockets.serve(self.server, self.host, self.port):
print(f"Server started : {self.host}:{self.port}")
await asyncio.Future()
if __name__ == "__main__":
print('WebSocketServer start')
server = WebSocketServer("0.0.0.0", 4545)
asyncio.run(server.start())
いざサーバーへ
ここまでは順調に事が運んだ。
だがしかし、Godotの資材をHTTPSに配置し実行してもうんともすんとも言わないのである。
というわけで、Godotの有識者が集まるDiscordサーバへお邪魔しスレ立てを行いました。
するとこのような回答が。
▼ お返事
「nginx上にシンプルなwebsocket実装のjsファイルを置いて、そこからpython側に通信できるかは試してみましたか?」
そうじゃん!
バケモンにはバケモンをぶつけるのは映画だけ、まずはシンプルな状態でアプローチをかけて問題の切り分けを行うのが鉄則でございます。
Godotもふたを開ければjsファイル吐き出しているっぽいし、簡単なNodeJSで作ってぶつけちゃおう。
使用したテストコード
const WebSocket = require('ws');
const ws = new WebSocket('ws://192.168.3.251:4545');
ws.on('open', function open() {
console.log('Connected to server');
ws.send('Hello, server!');
});
ws.on('message', function incoming(message) {
console.log('Received: %s', message);
});
結果:NG
ってことはサーバー側があかんのとちゃいます?
サーバ側をPythonからNodeJSでやってみる
const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');
const options = {
key: fs.readFileSync('/etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/cert.pem')
};
const server = https.createServer(options);
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
console.log('Client connected');
ws.on('message', function incoming(message) {
console.log('Received: %s', message);
});
ws.send('Hello, client!');
});
server.listen(4545, '0.0.0.0', function() {
console.log('Server is listening on port 4545');
});
なんと結果はOKだったんですね。
スクリーンショットとっておけばよかったと後悔
その時梨に電流走る
(あれ?フォントタグ使ってもフォントのサイズ変わらないの!?)
NodeJSでバックエンド作ってしまえば通信が確立するのでは?
とりあえずGodotのプロジェクトをHTML5形式でエクスポートしアップロード
何やら繋がっている模様
動くやん・・・
そういえばPythonでSSL証明書読み込むやつ書いたっけ?
import ssl
import pathlib
import asyncio
import websockets
# SSL証明書と秘密鍵のパス
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain('/etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/cert.pem', '/etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/privkey.pem')
# 接続時の処理
async def handle_connection(websocket, path):
print('Client connected')
try:
# メッセージ受信待機
async for message in websocket:
print('Received:', message)
# クライアントにメッセージを返信
await websocket.send('Server received: ' + message)
except websockets.exceptions.ConnectionClosedError:
pass
finally:
print('Client disconnected')
# WebSocketサーバーを作成し、SSLで接続を待機
start_server = websockets.serve(
handle_connection, '0.0.0.0', 4545, ssl=ssl_context
)
# サーバーを起動
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
結果NG(スクリーンショット撮ってなかったなぁ。。。)
とりあえず現状動いているNodeJSをバックエンドの言語に採用することにしました。
Pythonファンの方ごめんなさい!!(Pythonでやりたかったなぁ・・・誰か有識者の方教えてください!)
設定ファイルの整理
NodeJSで作るサーバもどうせならDocker-Composeにまとめる。
Pythonでサーバを作ることはあきらめてないけど、調査は打ち切りで未来の君たちに託す!
とりあえず自分の環境ではこれで動いたというものを置いておく
docker-compose.yml
version: '3'
services:
nginx:
image: nginx:latest
ports:
- "1010:1010"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl.conf:/etc/nginx/conf.d/ssl.conf
- ./html:/usr/share/nginx/html
- /etc/letsencrypt:/etc/letsencrypt:ro
depends_on:
- nodeapp # nginxがnodeappに依存していることを指定
restart: always
nodeapp:
image: node:latest
working_dir: /usr/src/app
ports:
- "4545:4545"
volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro
- ./server:/usr/src/app
command: node server.js # アプリケーションのエントリーポイントを指定するコマンド
restart: always
networks:
default:
driver: bridge
nginx.conf
events {}
http {
include /etc/nginx/conf.d/*.conf;
}
ssl.conf
server {
listen 1010 ssl;
server_name [NoIPあたりで取得したドメイン];
ssl_certificate /etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Cross-Origin-Embedder-Policyヘッダーを設定
add_header Cross-Origin-Embedder-Policy "require-corp";
# Cross-Origin-Opener-Policyヘッダーを設定
add_header Cross-Origin-Opener-Policy "same-origin";
include mime.types;
default_type application/octet-stream;
types {
text/javascript js;
application/javascript js;
}
location / {
root /usr/share/nginx/html;
index index.html;
}
}
server.js
const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');
const options = {
key: fs.readFileSync('/etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/[NoIPあたりで取得したドメイン]/cert.pem')
};
const server = https.createServer(options);
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
console.log('Client connected');
ws.on('message', function incoming(message) {
console.log('Received: %s', message);
});
ws.send('Hello, client!');
});
server.listen(4545, '0.0.0.0', function() {
console.log('Server is listening on port 4545');
});
ディレクトリ構成
root/
┣docker-compose.yml
┣nginx.conf
┣ssl.conf
┣server/
┃┗server.js
┗html/
┗Godotがエクスポートした資材を丸ごと配置
謎はまだまだ!調べないといけないこと
じつはほかにも気になっていることがあって、これは仕様なのかどうなのかがわからないんでござ。
今後GodotのDiscordサーバーにスレ立てするかもしれません。