MyEnigma

とある自律移動システムエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

Web初心者のためのWebSocket概要と各言語におけるサンプルコード


WebSocket: Lightweight Client-Server Communications (English Edition)

目次

はじめに

以前、通常のHTTPを使った、

簡単なプロセス間通信の方法を記事にしましたが、

myenigma.hatenablog.com

myenigma.hatenablog.com

 

通常のHTTPでは、

通信方式request-response型なので、

クライアントがサーバに話しかけないと、

サーバが、クライアントに話しかけることができませんでした。

そこでウェブアプリケーションにおいて、

双方通信によく使われるのがWebSocketです。

ja.wikipedia.org

今回はこのWebSocketについて概要と

各言語でのサンプルコードを紹介したいと思います。  

WebSocketとは?

WebSokectは、ウェブアプリケーションにおいて、

双方向通信を実現するための技術です。

qiita.com

qiita.com

RFC 6455として、規格化されています。

 

通常のHTTPとは異なり、

WebSocketでは、同じセッションの中で、

クライアントからサーバに複数回データを送信することができますし、

サーバからクライアントに複数回データを送信することができます。

 

このWebソケットは、チャットアプリなど、

サーバから、クライアントにpushする形で、

リアルタイム性の高い通信を必要とするアプリで利用されています。

 

Pythonにおけるサンプルコード

PythonでWebSocketを使いたい場合は、

色々ライブラリは存在しますが、

今回は、websocketsというライブラリを使います。

websockets.readthedocs.io

インストールは、

$ pip install websockets

でインストールできます。

 

例えば、下記のようなWebSocketサーバーコードを作成し、

"""
A websocket server example

author: Atsushi Sakai

"""

import asyncio
import websockets
import time


def main():
    print("start!!")

    async def hello(websocket, path):
        name = await websocket.recv()
        print(f"< {name}")

        for i in range(10):
            greeting = f"Hey {name}!"
            await websocket.send(greeting)
            print(f"> {greeting}")
            time.sleep(3)

    start_server = websockets.serve(hello, "localhost", 8765)

    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()

    print("done!!")


if __name__ == '__main__':
    main()

下記のような、クライアントコードを作成します。

"""
A websocket client example

author: Atsushi Sakai

"""

import asyncio
import websockets

def main():
    print("start!!")

    async def hello():
        uri = "ws://localhost:8765"
        async with websockets.connect(uri) as websocket:
            name = input("What's your name? ")

            await websocket.send(name)
            print(f"> {name}")

            while True:
                greeting = await websocket.recv()
                print(f"< {greeting}")

    asyncio.get_event_loop().run_until_complete(hello())

    print("done!!")


if __name__ == '__main__':
    main()

サーバに対して、クライアントが名前を言うと、

サーバが3秒に一回、Hey + 名前と10回返してくれます。

f:id:meison_amsl:20201010141823p:plain

 

このように、サーバ側がクライアント側に話しかけることができるのは、

WebSocketの特徴です。

 

Juliaにおけるサンプルコード

JuliaでWebSocketを使いたい場合は、

HTTP.jlを使うことができます。

github.com

 

例えば、下記のようなWebSocketサーバーのコードを作成し、

"
 A Web socket server sample 

 author: Atsushi Sakai
"

using HTTP

function main()
    println(PROGRAM_FILE, " start!!")

    HTTP.WebSockets.listen("127.0.0.1", UInt16(8081)) do ws
        while !eof(ws)
            data = readavailable(ws)
            write(ws, data)
            println("request received!!")

            for i in 1:10
                println("Say hey")
                sleep(3)
                write(ws, "Hey")
            end
        end
    end

    println(PROGRAM_FILE, " Done!!")
end

if abspath(PROGRAM_FILE) == @__FILE__
    @time main()
end

クライアントのコードは下記のようにすると、

"
 Web socket client sample 

 author: Atsushi Sakai
"

using HTTP

function main()
    println(PROGRAM_FILE, " start!!")

    HTTP.WebSockets.open("ws://127.0.0.1:8081") do ws
        write(ws, "Hello")

        while true
            x = readavailable(ws)
            @show x
            println(String(x))
        end
    end

    println(PROGRAM_FILE, " Done!!")
end

if abspath(PROGRAM_FILE) == @__FILE__
    @time main()
end

ほぼ、Pythonのサンプルコードと同じですが、

サーバに対して、クライアントがHelloと言うと、

サーバが3秒に一回、Heyと10回返してくれます。

f:id:meison_amsl:20201010133908p:plainf:id:meison_amsl:20201010133919p:plain

サンプルコードのリポジトリ

上記のサンプルコードは

すべて下記のGitHubのリポジトリ上でも公開しています。 

github.com

 

参考資料

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com


WebSocket: Lightweight Client-Server Communications (English Edition)

MyEnigma Supporters

もしこの記事が参考になり、

ブログをサポートしたいと思われた方は、

こちらからよろしくお願いします。

myenigma.hatenablog.com