socketIO 관련 프로젝트를 하면서 NodeJS를 처음부터 사용할 생각은 아니었지만

어쩌다가 Flask를 이용한 socketIO를 사용하게 되어 간단한 구조를 살펴보고 제가 작성한 코드를

올리려고 합니다.

우선 이 Flask socketIO란 놈은 구버전 익스플로러같은 곳에서는 수신이 안될 수 있으니 주의하시기 바랍니다.

저도 그것때문에 NodeJS socketIO로 바꿨습니다. 그것 빼고는 아주 무난하게 동작합니다.

from flask import Flask, render_template
from flask_socketio import SocketIO, emit

우선 해당 라이브러리들을 임포트해줍니다.

그리고 플라스크 socketIO 객체를 생성합니다.

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

 

그리고 밑에 코드는 써도 좋고 안써도 좋습니다. 결과를 관찰하기 위해 html 템플릿을 렌더시킨 것이기 때문입니다.

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

 

그리고 run을 시켜주면 되는데요.

global app
socketio.run(app, host='0.0.0.0', port=5555)

저는 포트넘버를 5555로 잡았습니다.

 

그리고 간단한 수신부 코드를 만들어 보았습니다.  수신부 명을 ‘real_time’ 이라고 임의로 지어 주고, send_data라는 함수명은 아무렇게 지어줘도 상관없습니다.

그리고 함수명 옆에 message라는 파라미터는 발신부에서 보내주는 데이터를 받아올 수 있는 파라미터입니다.

@socketio.on('real_time')
def send_data(message):

    from datetime import datetime
    global timecheck
    global result


    try:
        now = str(datetime.utcnow().replace(microsecond=0))
        if timecheck == now:
            emit('fromserver', json.dumps({'data': result['data']}))

        else:
            get = {"time": now}
            result = db["buffer"].find_one(get)

            emit('fromserver', json.dumps({'data': result['data']}))
            timecheck = now

    # exception handling
    except:
        # db.close()
        print("occur exeption" + format_exc())

저는 수신부와 연결된 모든 클라이언트에게 전송할 것이기 때문에 emit함수를 사용하였는데요, 사용 목적에 따라 함수 선택 해주시면 됩니다.

자세한 설명은 flask-socketIO 문서를 참고하세요.

 

이 단락의 코드를 간단히 설명하자면 ‘real_time’ 이라는 수신부로 받은 소켓데이터에서 message 파라미터는 이용하지 않았지만 현재 시간을 기준으로 db[“buffer”]에 있는 데이터를 얻어 json으로 파싱하여 모든 클라이언트에 전송하는 로직의 코드입니다.

풀 소스코드는 아래에 첨부하였습니다.

# -*- coding: utf8 -*-
import multiprocessing
import pandas as pd
from pandas.tseries.offsets import Hour, Minute, Second
import json

from traceback import format_exc

from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client['seismic']

timecheck = ""
result = []


from flask import Flask, render_template
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

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


class IO_Socket(multiprocessing.Process):

    """client connection generator"""

    def __init__(self):

        """
        constructor for multiprocessing

        """

        multiprocessing.Process.__init__(self)
        self.__suspend = False
        self.__exit = False


    def run(self):

        """Process start method"""

        # wrap Flask application with socketio's middleware
        global app

        socketio.run(app, host='0.0.0.0', port=5555)

    def mySuspend(self):
        self.__suspend = True

    def myResume(self):
        self.__suspend = False

    def myExit(self):
        self.__exit = True


@socketio.on('real_time')
def send_data(message):

    from datetime import datetime
    global timecheck
    global result


    try:
        now = str(datetime.utcnow().replace(microsecond=0) + Hour(9) - Second(5))
        if timecheck == now:
            emit('fromserver', json.dumps({'data': result['data']}))

        else:
            get = {"time": now}
            result = db["buffer"].find_one(get)

            emit('fromserver', json.dumps({'data': result['data']}))
            timecheck = now

    # exception handling
    except:
        # db.close()
        print("occur exeption" + format_exc())
        # pass
    # else:
    #     print('off mode')
    #     pass
    # else:
    #     send_by_time(message)

 

전체 코드 중에서 몽고 디비를 같이 쓰긴 했지만 쓰시는 목적에 따라 코드 변경해 주시면 됩니다.