ProgramingTip

webSocket을 사용하여 특정 사용자에게 메시지를 보내 시나요?

bestdevel 2020. 11. 21. 09:30
반응형

webSocket을 사용하여 특정 사용자에게 메시지를 보내 시나요?


모든 사용자에게 메시지를 방송하는 코드를 작성했습니다 .

사용 된 코드 : (간단)

// websocket and http servers
var webSocketServer = require('websocket').server;

...
...
var clients = [ ];

var server = http.createServer(function(request, response) {
    // Not important for us. We're writing WebSocket server, not HTTP server
});
server.listen(webSocketsServerPort, function() {
  ...
});

var wsServer = new webSocketServer({
    // WebSocket server is tied to a HTTP server. 
    httpServer: server
});


    // This callback function is called every time someone
    // tries to connect to the WebSocket server
    wsServer.on('request', function(request) {
    ...
    var connection = request.accept(null, request.origin); 
    var index = clients.push(connection) - 1;
    ...

주의하십시오 :

  • 사용자 참조가 없지만 연결 만 있습니다.
  • 모든 사용자 연결은 array.

목표 : NodeJs 서버가 특정 클라이언트 (John) 에게 메시지를 보내려고 가정 해 보겠습니다 .

그리고 여기에 질문이 있습니다.

  • NodeJs 서버는 John이 어떤 연결을 가지고 어떻게 알 수 있습니까?

    NodeJs 서버는 훌륭합니다. 보이는 것은 연결뿐입니다.

따라서 이제는 사용자의 연결만으로 사용자를 저장해서는 안되며 , 대신 개체를 포함 개체 를 저장해야 우리 합니다.userIdconnection

그리고 여기 내 생각이 있습니다.


  • 페이지로드가 완료되면 (Dom 준비) -NodeJs 서버에 대한 연결을 설정합니다.

  • NodeJs 서버가 연결을 수락하면 한 웹을 생성하여 클라이언트 브라우저로 보냅니다. 사용자 연결 및 고유 노드를 개체에 저장합니다. 예 : {UserID:"6" , value :{connectionObject}}

  • 클라이언트 측 에서이 메시지가 도착하면 숨겨진 필드 또는 쿠키에 저장하십시오. (향후 NodeJs 서버에 대한 요청)


서버가 John에게 메시지를 보내려고 할 때 :

  • 사전에서 john의 UserID를 찾아 해당 연결로 메시지를 보냅니다.

여기에 등록 된 asp.net 서버 코드가 없습니다. NodeJ 만.

질문 :

이것이 올바른 방법입니까? (또는 내가 뭔가를 놓친 적이 있습니까?)


이것은 올바른 방법 일뿐 아니라 유일한 방법입니다. 기본적으로 각 연결에는 고유 한 ID가 필요합니다. 검증 할 것입니다. 그렇게 간단합니다.

이제 그것을 어떻게 표현할지는 다른 것입니다. idconnection속성을 사용 하여 개체를 만드는 것을 수행하는 좋은 방법입니다 (확실히 갈 것입니다). id연결 개체에 직접 수도 있습니다 .

또한 사용자는 통신을 원하는 경우 사용자의 ID도 전송해야합니다. 즉, 사용자 A가 사용자 B에게 메시지를 보내고 싶을 때 A는 B의 ID를 알아야합니다.


다음은 간단한 채팅 서버 비공개 / 직접 메시징입니다.

package.json

{
  "name": "chat-server",
  "version": "0.0.1",
  "description": "WebSocket chat server",
  "dependencies": {
    "ws": "0.4.x"
  }
}

server.js

var webSocketServer = new (require('ws')).Server({port: (process.env.PORT || 5000)}),
    webSockets = {} // userID: webSocket

// CONNECT /:userID
// wscat -c ws://localhost:5000/1
webSocketServer.on('connection', function (webSocket) {
  var userID = parseInt(webSocket.upgradeReq.url.substr(1), 10)
  webSockets[userID] = webSocket
  console.log('connected: ' + userID + ' in ' + Object.getOwnPropertyNames(webSockets))

  // Forward Message
  //
  // Receive               Example
  // [toUserID, text]      [2, "Hello, World!"]
  //
  // Send                  Example
  // [fromUserID, text]    [1, "Hello, World!"]
  webSocket.on('message', function(message) {
    console.log('received from ' + userID + ': ' + message)
    var messageArray = JSON.parse(message)
    var toUserWebSocket = webSockets[messageArray[0]]
    if (toUserWebSocket) {
      console.log('sent to ' + messageArray[0] + ': ' + JSON.stringify(messageArray))
      messageArray[0] = userID
      toUserWebSocket.send(JSON.stringify(messageArray))
    }
  })

  webSocket.on('close', function () {
    delete webSockets[userID]
    console.log('deleted: ' + userID)
  })
})

명령

테스트하려면 실행 npm install하여 ws. 그런 다음 채팅 서버를 시작하려면 하나의 터미널 탭에서 실행 node server.js(또는 npm start)합니다. 그런 다음 다른 터미널 탭에서을 실행합니다 wscat -c ws://localhost:5000/1. 여기서는 1연결하는 사용자의 사용자 ID입니다. 그런 다음 세 번째 터미널 탭에서을 실행 wscat -c ws://localhost:5000/2한 다음 사용자로부터에 메시지를 보내 2려면 1을 입력 ["1", "Hello, World!"]합니다.

단점

이 채팅 서버는 매우 간단합니다.

  • 고집

    PostgreSQL과 같은 데이터베이스에 메시지를 저장하지 않습니다. 따라서 메시지를 보내는 사용자는 메시지를 받으려면 서버에 연결되어 있어야합니다. 그렇지 않으면 메시지가 손실됩니다.

  • 보안

    안전하지 않습니다.

    • 서버의 URL과 Alice의 사용자 ID를 알고 있으면 Alice를 가장 할 수 있습니다. 즉, Alice로 서버에 연결하여 그녀의 새 수신 메시지를 수신하고 그녀의 메시지를 내가 아는 사용자 ID를 가진 모든 사용자에게 보낼 수 있습니다. 보안을 강화하려면 연결할 때 사용자 ID 대신 액세스 토큰을 허용하도록 서버를 수정하십시오. 그러면 서버는 액세스 토큰에서 사용자 ID를 가져와 인증 할 수 있습니다.

    • WebSocket Secure ( wss://) 연결을 지원하는지 확실하지 않습니다. 에서만 테스트했기 때문에에서 localhost안전하게 연결하는 방법도 모르겠습니다 localhost.


내가 한 일을 공유하고 싶습니다. 시간을 낭비하지 않기를 바랍니다.

필드 ID, IP, 사용자 이름, 로그인 시간 및 로그 아웃 시간을 포함하는 데이터베이스 테이블을 만들었습니다. 사용자가 로그인 할 때 로그인 시간은 현재 unixtimestamp unix가됩니다. 그리고 websocket 데이터베이스에서 연결이 시작되면 가장 큰 로그인 시간을 확인합니다. 사용자가 로그인 한 상태가됩니다.

그리고 사용자가 로그 아웃하면 현재 로그 아웃 시간이 저장됩니다. 사용자는 앱을 떠난 사람이됩니다.

새 메시지가있을 때마다 Websocket ID와 IP를 비교하여 관련 사용자 이름이 표시됩니다. 다음은 샘플 코드입니다 ...

// when a client connects
function wsOnOpen($clientID) {
      global $Server;
      $ip = long2ip( $Server->wsClients[$clientID][6] );

      require_once('config.php');
      require_once CLASSES . 'class.db.php';
      require_once CLASSES . 'class.log.php';

      $db = new database();
      $loga = new log($db);

      //Getting the last login person time and username
      $conditions = "WHERE which = 'login' ORDER BY id DESC LIMIT 0, 1";
      $logs = $loga->get_logs($conditions);
      foreach($logs as $rows) {

              $destination = $rows["user"];
              $idh = md5("$rows[user]".md5($rows["time"]));

              if ( $clientID > $rows["what"]) {
                      $conditions = "ip = '$ip', clientID = '$clientID'  

                      WHERE logintime = '$rows[time]'";
                      $loga->update_log($conditions);
             }
      }
      ...//rest of the things
} 

흥미로운 게시물 (내가하는 일과 유사). 디스펜서를 WebSocket과 연결하는 API (C #)를 만들고 있습니다. 각 디스펜서에 대해 WebSocket과 DispenserId를 저장하는 ConcurrentDictionary를 생성하여 각 Dispenser가 WebSocket을 쉽게 생성하고 나중에 스레드 문제없이 사용할 수 있도록합니다 (특정 함수 호출). GetSettings 또는 RequestTicket과 같은 WebSocket에서). 예제의 차이점은 배열 대신 ConcurrentDictionary를 사용하여 각 요소를 분리한다는 것입니다 (JavaScript에서는 이러한 작업을 시도하지 않음). 친애하는,


사용하는 사람의 경우 ws버전 3 이상을. @ ma11hew28에서 제공하는 답변을 사용하려면이 블록을 다음과 같이 변경하면됩니다.

webSocketServer.on('connection', function (webSocket) {
  var userID = parseInt(webSocket.upgradeReq.url.substr(1), 10)
webSocketServer.on('connection', function (webSocket, req) {
  var userID = parseInt(req.url.substr(1), 10)

ws 패키지 이동 upgradeReq 요청 개체에 대한 자세한 내용은 다음 링크를 확인할 수 있습니다.

참조 : https://github.com/websockets/ws/issues/1114

참고 URL : https://stackoverflow.com/questions/16280747/sending-message-to-a-specific-connected-users-using-websocket

반응형