Отправка сообщения конкретным подключенным пользователям с помощью 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 хочет отправить сообщение на конкретные клиент (Джон).
и вот вопрос :
-
как сервер NodeJs узнает, какое соединение имеет Джон ?
сервер NodeJs даже не знает Джона. все это видит соединения.
так ,
Я считаю, что теперь я не должен хранить пользователей только по их соединению, вместо этого мне нужно хранить объект -- который будет содержать userId
и connection
объект.
и вот моя мысль :
после завершения загрузки страницы (DOM ready) - установите соединение с сервером NodeJs.
когда сервер NodeJs принимает соединение-создайте уникальную строку и отправьте ее в браузер клиента. Сохраните пользовательское соединение и уникальную строку в объекте. например
{UserID:"6" , value :{connectionObject}}
на стороне клиента, когда это сообщение прибывает - храните его в скрытом поле или куки. (для будущих запросов к серверу NodeJs )
когда сервер хочет отправить сообщение Джону:
- найти идентификатор пользователя Джона в словаре и отправить сообщение по соответствующему соединению.
пожалуйста, обратите внимание, что нет asp.net код сервера invloced здесь (в механизме сообщения). только NodeJs .
вопрос :
это правильный путь ? (или я что-то пропустил ?)
3 ответа:
Это не только правильный путь, но единственный способ. В основном каждое соединение нуждается в уникальном идентификаторе. В противном случае вы не сможете их идентифицировать, это так просто.
Теперь, как вы будете представлять его это разные вещи. Создание объекта с помощью
id
иconnection
свойства-это хороший способ сделать это (я бы определенно пошел на это ). Вы также можете прикрепитьid
непосредственно к объекту связи.также помните, что если вы хотите общения между пользователями, то вы должны отправить идентификатор целевого пользователя, а также, т. е. когда пользователь A хочет отправить сообщение пользователю B, то, очевидно, A должен знать идентификатор B.
вот простой чат-сервер частных / прямых сообщений.
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
- это идентификатор пользователя подключающегося пользователя. Затем на третьей вкладке терминала запуститеwscat -c ws://localhost:5000/2
, а затем, чтобы отправить сообщение от пользователя2
до1
введите["1", "Hello, World!"]
.недостатки
этот чат-сервер очень просто.
настойчивость
он не хранит сообщения в базе данных, таких как PostgreSQL. Таким образом, пользователь, которому вы отправляете сообщение, должен быть подключен к серверу для его получения. В противном случае, сообщение будет потеряно.
безопасность
это небезопасный.
если я знаю URL сервера и идентификатор пользователя Алисы, то я могу олицетворять Алису, т. е. подключаться к серверу как к ней, позволяя мне получать ее новые входящие сообщения и отправлять сообщения от нее любому пользователю, чей идентификатор пользователя я также знаю. Чтобы сделать его более безопасным, измените сервер, чтобы он принимал ваш маркер доступа (вместо вашего идентификатора пользователя) при подключении. Затем сервер может получить Ваш идентификатор пользователя из маркера доступа и пройти проверку подлинности вы.
я не уверен, что он поддерживает WebSocket Secure (
wss://
) соединения, так как я только проверил его наlocalhost
, и я не уверен, как безопасно подключиться отlocalhost
.
Я хотел бы поделиться тем, что я сделал. Надеюсь, это не будет пустой тратой времени.
Я создал таблицу базы данных, содержащую поле ID, IP, имя пользователя, logintime и logouttime. Когда пользователь входит в logintime будет currect unixtimestamp. И когда соединение запускается в базе данных websocket проверяет наличие самого большого logintime. Это будет прийти пользователь вошел в систему.
и когда пользователь выходит из системы он будет хранить currect logouttime. Пользователь станет тем, кто оставил приложение.
всякий раз, когда появляется новое сообщение, 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 }