2016-03-22 14 views
1

anglejsとsocketioチャットアプリで実行している問題は、別のユーザーにメッセージを送信するときに、メッセージを表示するイベントハンドラが複数回トリガされるためです画面に同じメッセージが2回以上表示され、メッセージを1回だけ表示することができます。誰かがなぜこれが起こっているのか、この問題を解決する方法を説明することができますか?Angularjs SPA + Flask-Socketioイベントが複数回発生する

ここに私のクライアントサイドコードがあります。私はページを変更するためにngRouteを使用し、ページを切り替えるときにデータを保持するサービスを使用しています。

 // This method populates the chatbox on startup 
    // Also it is emitted to on server side to display a new message 
    socket.on("populateMessagesArchived", function (message) { 
     $scope.tempArray = [message[0], message[1], message[2]]; 
     $scope.messages.push($scope.tempArray); 
     $scope.$apply(); 
     $scope.tempArray = []; 
     $scope.message=""; 
    }); 


    // When a users sends a message, this is invoked 
    // this function gets the roomNum and message where roomNum corresponds to the roomNum where user sent message 
    $scope.getMessage = function(roomNum, message) { 
     $scope.tempArray = [roomNum, message, $scope.username]; 
     $scope.messages.push($scope.tempArray); 
     socket.emit("storeMessagesInDatabase", {"uuid": $scope.uuid, "message": message, "roomNum": roomNum, "username": $scope.username}); 
     var element = document.getElementById('msgpane'); 
     element.scrollTop = element.scrollHeight;  
     $scope.tempArray = []; 
     $scope.message=""; 
    }; 

サーバコード: は、基本的には、PostgreSQLデータベースにメッセージを追加します。ログインの確認と登録を処理します。しかし、私は問題がここにあるとは思わない。私が気づいたのは、別のsocketio接続が作られたページを切り替えるときです。 socketio接続の量は、出力されるメッセージの数に対応します。しかし、私はこの問題を解決する方法がわかりません。どんな助けでも大歓迎です。

@socketio.on('userLoggedIn', namespace='/iss') 
def loggedIn(user):   
    userData = user 
    connect = connectToDB() 
    cursor = connect.cursor(cursor_factory=psycopg2.extras.DictCursor) 
    cursor.execute("""select uuid, username from users WHERE username = %s AND password = crypt(%s, password);""", (userData['username'], userData['password'])) 
    #query1 = cursor.mogrify("""select * from users WHERE username = %s AND password = 'crypt(%s, password)';""", (userData['username'], userData['password'])) 
    query = cursor.fetchone() 
    if query is not None: 
     # Here we get the messages from the database and pass them to client side 
     tempArray = retrieveMessagesFromDB() 
     print tempArray 
     emit('userAuthorized', query["uuid"], namespace='/iss') 

     for message in tempArray: 
      // emitted to client side to populate the chat room on login of a user 
      emit("populateMessagesArchived", message, namespace='/iss') 
    else: 
     emit('userNotAuthorized', namespace='/iss') 

# 
# retrieves the messages from the database to populate the chat rooms 
# 
def retrieveMessagesFromDB(): 
    connect = connectToDB() 
    cursor = connect.cursor(cursor_factory=psycopg2.extras.DictCursor) 
    cursor.execute("""select messages.room_num, messages.message, users.username from users join messages on users.uuid = messages.uuid;""") 
    query = cursor.fetchall() 
    return query 

# 
# storeMessagesInDatabase - stores messages in the database 
# 
@socketio.on('storeMessagesInDatabase', namespace='/iss') 
def storeMessagesInDatabase(userInfo): 
    # userInfo is Json and we set it equal to tempDict 
    tempDict=userInfo 
    tempArray=[] 
    tempArray.append(tempDict["roomNum"]) 
    tempArray.append(tempDict["message"]) 
    tempArray.append(tempDict["username"]) 
    connect = connectToDB() 
    cursor = connect.cursor() 

    try: 
     cursor.execute("""insert into messages (uuid, message, room_num) values (%s, %s, %s);""", (str(tempDict["uuid"]), tempDict["message"], str(tempDict["roomNum"]))) 
    except: 
     connect.rollback() 
    connect.commit() 
    # Messages emitted back to client to be outputted on screen 
    emit("populateMessagesArchived", tempArray, namespace='/iss', broadcast=True) 
    tempArray=[] 
+0

[編集] [MCVE]にこれを減らすためにしてください。 – davidism

+0

@ダビデミズムはこれが優れていますか? – sebenalern

答えて

0

私の問題を解決する方法は、angle-socket-ioライブラリを使用することでした。これは、メッセージハンドラの重複を止めるためのforward()関数を提供し、メッセージの繰り返しを解決します。また、私はMPAがページスイッチ上のソケットを破壊し、SPAが破壊しないことを理解しました。私は一度だけ呼び出される上位レベルのモジュールにsocketioコードを配置することをお勧めします。説明のよりは、ここを参照してください:

https://stackoverflow.com/a/36223423/3103677

関連する問題