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 서버는 훌륭합니다. 보이는 것은 연결뿐입니다.
따라서 이제는 사용자의 연결만으로 사용자를 저장해서는 안되며 , 대신 및 개체를 포함 할 개체 를 저장해야 우리 합니다.userId
connection
그리고 여기 내 생각이 있습니다.
페이지로드가 완료되면 (Dom 준비) -NodeJs 서버에 대한 연결을 설정합니다.
NodeJs 서버가 연결을 수락하면 한 웹을 생성하여 클라이언트 브라우저로 보냅니다. 사용자 연결 및 고유 노드를 개체에 저장합니다. 예 :
{UserID:"6" , value :{connectionObject}}
클라이언트 측 에서이 메시지가 도착하면 숨겨진 필드 또는 쿠키에 저장하십시오. (향후 NodeJs 서버에 대한 요청)
서버가 John에게 메시지를 보내려고 할 때 :
- 사전에서 john의 UserID를 찾아 해당 연결로 메시지를 보냅니다.
여기에 등록 된 asp.net 서버 코드가 없습니다. NodeJ 만.
질문 :
이것이 올바른 방법입니까? (또는 내가 뭔가를 놓친 적이 있습니까?)
이것은 올바른 방법 일뿐 아니라 유일한 방법입니다. 기본적으로 각 연결에는 고유 한 ID가 필요합니다. 검증 할 것입니다. 그렇게 간단합니다.
이제 그것을 어떻게 표현할지는 다른 것입니다. id
및 connection
속성을 사용 하여 개체를 만드는 것을 수행하는 좋은 방법입니다 (확실히 갈 것입니다). 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 요청 개체에 대한 자세한 내용은 다음 링크를 확인할 수 있습니다.
'ProgramingTip' 카테고리의 다른 글
C ++에서 돌아가는 가장 좋은 방법은 무엇입니까? (0) | 2020.11.21 |
---|---|
루비에서 to_s 대 to_str (그리고 to_i / to_a / to_h 대 to_int / to_ary / to_hash) (0) | 2020.11.21 |
java.lang.NumberFormatException을 어떻게해야합니까? 입력의 경우 :“N / A”? (0) | 2020.11.21 |
.map () 자바 펼쳐 ES6 맵? (0) | 2020.11.21 |
const, let 및 var의 v8 JavaScript 성능 영향? (0) | 2020.11.21 |