最近RustやらPythonやらKotlinを触っています。
でも今回はNimでUDP通信(オンラインゲームサーバーっぽい)を試してみようというものです。
RustはMozzilaが推してるので情報が充実してきてるのですが、
いかんせんNimは…(泣)
なぜ今回Nimを選んだかというと、ズバリ処理速度です。
下記の記事を読んで、Nimダントツじゃん!となった次第です。
参考:http://h-miyako.hatenablog.com/entry/2015/01/23/060000
ちなみに環境はMacBook Pro (Mojave)で行いました。
MacでのNimの環境構築はこれだけ。
$ brew install nim
プロジェクトを作成するには以下
$ mkdir <プロジェクト名>
$ cd <プロジェクト名>
$ nimble init
一通りプロジェクト設定の質問に答えていくと
<プロジェクト名>.nimbleというファイルと、
srcフォルダが出来上がってると思います。
srcフォルダ配下には<プロジェクト名>.nimというファイルがあるので
ここに以下のサーバーの雛形を追加してみます。
import net
when isMainModule:
var socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
socket.bindAddr(Port(27960))
echo "server bound to port 27960"
while true:
var
data = ""
address = ""
length = 64
port: Port
discard socket.recvFrom(data, length, address, port)
echo address, " send ", data, " by ", $port<br>
こちらが記述できたら、以下でビルドします。
あ、Nimはインデントは2スペースなので要注意です。
$ nimble build
そうすると<プロジェクト名>のファイルがビルドされるので、
あとは実行!
$ ./<プロジェクト名>
これでサーバーが起動してechoで表示させていた「server bound to port 27960」の
メッセージが表示されるはずです。
では実際にUDPで叩いてみましょう。
クライアントはぶっちゃけPythonでもなんでもいいんですが、
せっかくなのでNimのソースコードを置いておきます。
先程の手順と同様にプロジェクト作って実行してください。
import net
when isMainModule:
var socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
socket.bindAddr(Port(27961))
socket.sendTo("127.0.0.1", Port(27960), "Hello!")
while true:
var
data = ""
address = ""
length = 64
port: Port
discard socket.recvFrom(data, length, address, port)
echo address, " send ", data, " by ", $port
Clientが27961ポート、サーバーが27960ポートを使用して通信します。
上手く実行できればサーバー側に「192.168.0.1 send Hello! by 27961」のように
表示されるはずです。
意外とnetライブラリの情報がなかったのでドキュメントみて頑張るしかなかった。。
さらにオンラインゲームだとユーザーの情報や、アイテムの情報など
データのフォーマットがあったほうがわかりやすいかと思いますので、
Jsonの受け渡し処理をそれぞれ追加したものを載せて、今回はここまでにしたいと思います。
Nimの普及を願って…!
import net
import json
when isMainModule:
var socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
socket.bindAddr(Port(27960))
echo "server bound to port 27960"
while true:
var
data = ""
address = ""
length = 64
port: Port
discard socket.recvFrom(data, length, address, port)
echo address, " send ", data, " by ", $port
var jsonStr = parseJson(data)
echo $jsonStr["key1"]
import net
import json
when isMainModule:
var socket = newSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
socket.bindAddr(Port(27961))
let jsonObj = %* { "key1": "value1", "key2": 1 }
socket.sendTo("127.0.0.1", Port(27960), $jsonObj)
while true:
var
data = ""
address = ""
length = 64
port: Port
discard socket.recvFrom(data, length, address, port)
echo address, " send ", data, " by ", $port