読者です 読者をやめる 読者になる 読者になる

CORDEA blog

Programming及びFedora21等のLinux OSのことが多めです。

Pythonのライブラリ、PodSixNetの使い方

Python

はじめに

 
使い方といっても、他のドキュメントがしっかり書いてあったりするので、1からすべて説明するというものではありません。

作者の方のサイトで説明を読んだけれど、実際にどう使ってわからない、といった方に向けて備忘録的に書いておきます。
あと、個々の関数やクラスの説明に関しては作者の方のサイトを見ていただければ幸いです。

 
この記事で最終的に出来上がるのはHello/Byeを交互に受発信するものです。

コードを全て見たい場合は下のGistをご参照ください。

サーバー/クライアント共通


PodSixNetでは次のようなディクショナリ形式のデータをやり取りします。
 

{"action": "myaction", "string": "apple", "boolean": "True", "integer": 1}


送信側は次のようにして送信します。

 

self.Send({"action": "myaction", "string": "apple", "boolean": "True", "integer": 1})

受信側は次のようにして受信します。

 

def Network_myaction(self, data):
    string  = data["string"]
    boolean = data["boolean"]
    integer = data["integer"]
    print(string)

この時、printされるのは"apple"になります。


 

サーバーサイド

class NewChannel(Channel):
    def __init__(self, *args, **kwargs):
        Channel.__init__(self, *args, **kwargs)
 
    def Network_getHello(self, data):
        print("network: hello")
        message = data["message"]
        self._server.allSendBye(message)
 
    def Network_getBye(self, data):
        print("network: bye")
        message = data["message"]
        self._server.allSendHello(message)


 
ここではクライアントサイドから送信されてきたメッセージを受け取っています。
allSendBye, allSendHelloについてはあとで出てきます。


 

class NewServer(Server):
    channelClass = NewChannel

    def __init__(self, *args, **kwargs):
        Server.__init__(self, *args, **kwargs)
        self.clients = {}
        self.clientNumber = 0
        print("Server launched")

    def Connected(self, channel, addr):
        print("New connection: " + str(channel))
        self.clients[self.clientNumber] = channel
        self.clientNumber += 1

 
ここでの__init__はサーバーを立ち上げた時に呼ばれます。
また、Connectedはクライアントとの接続が行われた際、クライアント毎に呼ばれます。
もし接続させるクライアント数を限定したければ、Connectedで処理すると楽です。


 
私の場合、クライアントの識別はディクショナリで行なっています。
ディクショナリのKeyはクライアントの番号、ValueはChannelです。

 

    def allSendHello(self, message):
        print("client message: " + message)
        clientList = self.clients.values()
        for i in clientList:
            i.Send({"action": "getHello", "message": "Hello Client!"})

    def allSendBye(self, message):
        print("client message: " + message)
        clientList = self.clients.values()
        for i in clientList:
            i.Send({"action": "getBye", "message": "Bye Client!"})

    def launch(self):
        while True:
            self.Pump()
            sleep(0.0001)


 
NewServerクラスの続きです。
allSendHello, allSendByeはその名の通り、接続しているクライアントすべてに対して送信しています。
ディクショナリに入っているValueをすべてリストに格納し、for文で全て取り出して送信しています。
この場合、iにはChannelが入っています。
Channelを指定することで送信する相手を決定することが可能です。



 

クライアントサイド


基本は変わりませんのでさくっと行きます。

 

class NetworkListener(ConnectionListener):
    def __init__(self, host, port):
        self.Connect((host, port))
        print("Client started")

    def Network_connected(self, data):
        print("Connected to the server")
        self.sendHello()

    def Network_disconnected(self, data):
        print("Disconnected from the server")

 
Network_connectedはサーバーに接続した時に呼ばれます。
Network_disconnectedサーバーから切断された時に呼ばれます。

 

    def sendHello(self):
        sleep(1.0)
        self.Send({"action": "getHello", "message": "Hello Server!"})

    def sendBye(self):
        self.Send({"action": "getBye", "message": "Bye Server!"})
        sleep(1.0)

 
ここではサーバーに対してメッセージを送信しています。



 

最後に


PodSixNetはターン制のゲームには非常に有効なライブラリです。
ぜひ使ってみてください。