PTVSのFlask上でSocketsを使ってWebSocketアプリ

#WebSocketとは
双方向通信であり、サーバとクライアント間でコネクションを確立し、コメントなどが送信されるとリアルタイムにそのコメントがコネクションを張っているクライアント全員に送られることでFacebookメッセンジャーやLineのようなチャットシステムを実現できる。このような双方向通信の仕組みをWebSocketという。

ちなみに余談としてポーリング方式があるが、websocketではコメントが送信された途端にサーバにパケットを送る仕組みになっているが、ポーリングでは、何秒間ごとにパケットを送り続け、コメントがされると送り続けているパケットにそのまま乗せてサーバに送る仕組みになる。よって、コメントが反映されるまで何秒間と大幅に遅れる上にパケットを送りつつづけるためサーバの負担が大きい。


#Flask上でWebSocketを実現
##Flaskのプロジェクトを作成
Visual Studio2015を開き、下記のように選択
**【新しいプロジェクト】▶︎【Python】▶︎【Web】▶︎【Flask Web Project】**

<img width="1274" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/130097/0d7b1fa8-8686-2d1f-f78c-7d1f32ec92aa.png">

##Websocketの導入
下記のようにプログラムを書き換えてください
参考にした[サイト](http://blog.kzfmix.com/entry/1380712277)

```Python:hello.html
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Test</title>
</head>
<body>
    <h1>Flaskでechoサーバー☆</h1>
    <form id="emit" method="POST" action='#'>
        <input type="text" name="emit_data" id="emit_data" placeholder="Message">
        <input type="submit" value="Echo">
    </form>
    <form id="broadcast" method="POST" action='#'>
        <input type="text" name="broadcast_data" id="broadcast_data" placeholder="Message">
        <input type="submit" value="Broadcast">
    </form>

    <ul id="log"></ul>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
    <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
    <script type="text/javascript" charset="utf-8">
        $(function () {
            namespace = '/test';
            var socket = io.connect('http://'+ document.domain+ ':' + location.port + namespace);
            $('form#emit').submit(function (event) {
                socket.emit('my event', { data: $('#emit_data').val() });
                return false;
            });
            $('form#broadcast').submit(function (event) {
                socket.emit('my broadcast event', { data: $('#broadcast_data').val() });
                return false;
            });

            socket.on('my response', function (msg) {
                $('#log').append('<br>' + $('<div/>').text('Received #' + msg.count + ': ' + msg.data).html());
            });
        })
    </script>
</body>
</html>
```

```Python:views.py
"""
Routes and views for the flask application.
"""

from datetime import datetime
from flask import render_template
from FlaskWebProject2 import app
from flask_sockets import Sockets

@app.route('/')
def hello():
    return render_template('hello.html')

if __name__ == '__main__':
    socketio.run(app, debug=True)
```


```Python:runserver.py
"""
This script runs the FlaskWebProject2 application using a development server.
"""

from os import environ
from FlaskWebProject2 import app
from flask import Flask, render_template, session, request         
from flask_socketio import SocketIO, emit, join_room, leave_room,close_room, rooms, disconnect   

async_mode = None
app.config['SECRET_KEY'] = 'secret!'

socketio = SocketIO(app)
thread = None

@socketio.on('my event', namespace='/test')
def test_message(message):
    session['receive_count'] = session.get('receive_count', 0) + 1
    emit('my response',{'data': message['data'], 'count': session['receive_count']})

@socketio.on('my broadcast event', namespace='/test')
def test_broadcast_message(message):
    session['receive_count'] = session.get('receive_count', 0) + 1
    emit('my response',{'data': message['data'], 'count': session['receive_count']},broadcast=True)

if __name__ == '__main__':

    HOST = environ.get('SERVER_HOST', 'localhost')
    try:
        PORT = int(environ.get('SERVER_PORT', '5555'))
    except ValueError:
        PORT = 5555
    socketio.run(app,HOST,PORT)
    #app.run(HOST, PORT)

```

##実行
VSをRunするすると下記の画像のようなページが開く
Echoという項目はエコーを返すだけです
<img width="1098" alt="１.png" src="https://qiita-image-store.s3.amazonaws.com/0/130097/755e5571-c86f-a66d-f056-c15bc3a0e071.png">

Broadcastという項目ではwebsoketを使って、コネクションを確立しているクライアントに同様にメッセージを送信するので、新しいタブを開くと**Broadcast**で送信した「**hello**」は反映されている
<img width="1095" alt="２.png" src="https://qiita-image-store.s3.amazonaws.com/0/130097/eeb5830b-84e6-fa47-9f2e-26175f70c227.png">

<img width="1097" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/130097/e303ba5f-3aca-74fb-ff18-3bff8a480d06.png">

#Azure上にデプロイ＆エラー
[こちら](http://qiita.com/saiyuki1919/items/db6f9a2c705a1c9135dc)の記事を参考にデプロイしてください
デプロイをするとScoketIOの読み込みエラーが発生してwebsocketされない
このエラーは多分、webからsocketioを読み込んでこなくてはならないのにAzureのフォルダーから読もうとしているのでエラーが起きていると考えられる。
![error.png](https://qiita-image-store.s3.amazonaws.com/0/130097/95542a6c-226d-959a-1e87-3b225becd38a.png)


**このエラーの解決方法をコメントなどでいただけるとありがたいです。探しても解決方法がわからなかったです**