Nodejs中关于socket.emit()的用法
Nodejs中关于socket.emit()的用法
我在《nodejs入门经典》看到一段代码 ##//HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Socket.io Express Example</title>
</head>
<body>
<h1>Socket.io Express Example</h1>
<form id="set-nickname">
<label for="nickname">Nickname:</label>
<input type="text" id="nickname" />
<input type="submit" />
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
jQuery(function ($) {
var nickName = $('#nickname');
var setNicknameForm = $('#set-nickname');
setNicknameForm.submit(function(event) {
event.preventDefault();
socket.emit('nickname', nickName.val(), function (data) {
if (data) {
console.log('Nickname set successfully');
setNicknameForm.hide();
} else {
setNicknameForm.prepend('<p>Sorry - that nickname is already taken.');
}
});
});
});
</script>
</body>
</html>
##//app.js
var app = require('express').createServer(),
io = require('socket.io').listen(app),
nicknames = [];
app.listen(3000);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
socket.on('nickname', function (data, callback) {
if (nicknames.indexOf(data) != -1) {
callback(false);
} else {
callback(true);
nicknames.push(data);
socket.nickname = data;
console.log('Nicknames are ' + nicknames);
}
});
socket.on('disconnect', function () {
if (!socket.nickname) return;
if (nicknames.indexOf(socket.nickname) > -1) {
nicknames.splice(nicknames.indexOf(socket.nickname), 1);
}
console.log('Nicknames are ' + nicknames);
});
});
###在HTML中
socket.emit('nickname', nickName.val(), function (data) {
if (data) {
console.log('Nickname set successfully');
setNicknameForm.hide();
} else {
setNicknameForm.prepend('<p>Sorry - that nickname is already taken.');
}
第三个参数是不是向服务器传了一个参数?
###在app.js中
socket.on('nickname', function (data, callback) {
if (nicknames.indexOf(data) != -1) {
callback(false);
} else {
callback(true);
nicknames.push(data);
socket.nickname = data;
console.log('Nicknames are ' + nicknames);
}
给传进的函数给上参数,但是这个函数不是应该在服务器端执行的么? 为什么用的是DOM的方法,在客户端执行了呢? 这个callback是怎么回事?
在Node.js中使用socket.emit()
方法可以将事件和数据发送到特定的WebSocket连接。下面是对你的问题的详细解释以及示例代码。
socket.emit()
的基本用法
socket.emit()
方法用于从客户端向服务器发送事件和数据。它接受两个或更多参数:
- 第一个参数是事件名称。
- 第二个参数(可选)是发送的数据。
- 第三个参数(可选)是一个回调函数,用于接收来自服务器的响应。
示例代码
HTML部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Socket.io Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<h1>Socket.io Example</h1>
<form id="set-nickname">
<label for="nickname">Nickname:</label>
<input type="text" id="nickname" />
<input type="submit" value="Submit" />
</form>
<script>
var socket = io.connect();
jQuery(function($) {
var nickName = $('#nickname');
var setNicknameForm = $('#set-nickname');
setNicknameForm.submit(function(event) {
event.preventDefault();
socket.emit('nickname', nickName.val(), function(data) {
if (data) {
console.log('Nickname set successfully');
setNicknameForm.hide();
} else {
setNicknameForm.prepend('<p>Sorry - that nickname is already taken.</p>');
}
});
});
});
</script>
</body>
</html>
Node.js服务器部分 (app.js
)
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
let nicknames = [];
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
socket.on('nickname', (data, callback) => {
if (nicknames.includes(data)) {
callback(false); // 针对客户端的回调
} else {
callback(true); // 针对客户端的回调
nicknames.push(data);
socket.nickname = data;
console.log('Nicknames are:', nicknames);
}
});
socket.on('disconnect', () => {
if (!socket.nickname) return;
if (nicknames.includes(socket.nickname)) {
nicknames.splice(nicknames.indexOf(socket.nickname), 1);
}
console.log('Nicknames are:', nicknames);
});
});
server.listen(3000, () => {
console.log('Server is running on port 3000');
});
解释
-
客户端发送事件:
socket.emit('nickname', nickName.val(), function(data) { if (data) { console.log('Nickname set successfully'); setNicknameForm.hide(); } else { setNicknameForm.prepend('<p>Sorry - that nickname is already taken.</p>'); } });
这里,
socket.emit('nickname', nickName.val())
发送一个名为'nickname'
的事件,并附带输入框中的值作为数据。回调函数会在接收到服务器响应后执行。 -
服务器处理事件:
socket.on('nickname', (data, callback) => { if (nicknames.includes(data)) { callback(false); } else { callback(true); nicknames.push(data); socket.nickname = data; console.log('Nicknames are:', nicknames); } });
服务器监听名为
'nickname'
的事件。当接收到事件时,检查昵称是否已存在。如果不存在,则添加到nicknames
数组中,并通过callback(true)
通知客户端。如果存在,则通过callback(false)
通知客户端。 -
回调函数: 回调函数在客户端执行,用于处理服务器的响应。它可以在客户端的脚本中定义并立即传递给
socket.emit()
。
通过这种方式,你可以实现客户端与服务器之间的双向通信,其中客户端可以发送请求并接收响应,而服务器可以处理这些请求并返回结果。
app.js中的callback(true)对应的就是html中的function (data),你可以把app.js中的callback(true)改为callback({name: ‘xiaoshan’}); html的function (data)中打印data.name,输出的就是xiaoshan
那为什么不把name这个参数传回去,而要在服务器调用这个函数呢?
socket.on('nickname', function (data, callback) {
if (nicknames.indexOf(data) != -1) {
callback(false);
} else {
callback(true);
nicknames.push(data);
socket.nickname = data;
console.log('Nicknames are ' + nicknames);
}
});
是上边的代码在起作用, 看了半天才找到原来官网上有给例子的
Sending and getting data (acknowledgements). – http://socket.io/#how-to-use
socket.emit()
方法用于从客户端向服务器发送事件。在你提供的例子中,socket.emit('nickname', nickName.val(), function (data) { ... })
发送了一个名为 'nickname'
的事件,并将 nickName.val()
作为数据传递给服务器。同时,它还接收一个回调函数,该回调函数在接收到服务器响应时执行。
客户端代码解析
在客户端(HTML 文件中的 JavaScript 代码):
socket.emit('nickname', nickName.val(), function (data) {
if (data) {
console.log('Nickname set successfully');
setNicknameForm.hide();
} else {
setNicknameForm.prepend('<p>Sorry - that nickname is already taken.</p>');
}
});
这里,nickName.val()
是要传递的数据,而回调函数会在服务器处理完请求后执行。如果服务器返回 true
,则表示昵称设置成功;否则表示昵称已存在。
服务器端代码解析
在服务器端 (app.js
):
io.sockets.on('connection', function (socket) {
socket.on('nickname', function (data, callback) {
if (nicknames.indexOf(data) != -1) {
callback(false); // 返回 false,表示昵称已存在
} else {
callback(true); // 返回 true,表示昵称可用
nicknames.push(data);
socket.nickname = data;
console.log('Nicknames are ' + nicknames);
}
});
// 其他逻辑...
});
服务器端接收到 'nickname'
事件后,检查 nicknames
数组中是否已存在该昵称。如果存在,则调用 callback(false)
返回错误信息;如果不存在,则添加到 nicknames
数组并调用 callback(true)
返回成功信息。
总结
socket.emit()
用于发送事件和数据。- 回调函数在服务器响应后在客户端执行。
callback
是一种机制,用于在异步操作完成后通知客户端或服务器结果。
这种设计使得客户端和服务器之间可以进行双向通信,从而实现更复杂的功能。