Nodejs框架里面集成websocket,用统一路由, 这样的框架有人用过吗?

Nodejs框架里面集成websocket,用统一路由, 这样的框架有人用过吗?

6 回复

当然可以。在Node.js中,将WebSocket集成到一个统一的路由系统中是一个常见的需求。这样的框架不仅能够提供WebSocket的支持,还能确保整个应用的路由逻辑保持一致。下面我将介绍一种使用expresssocket.io的方式来实现这一目标。

示例框架

我们可以使用Express作为HTTP服务器,并通过Socket.IO来处理WebSocket连接。这样,我们就可以利用Express的强大功能来管理路由,并通过Socket.IO来处理WebSocket通信。

安装依赖

首先,你需要安装必要的库:

npm install express socket.io

创建应用

接下来,我们创建一个简单的应用来演示如何整合这些技术:

// 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);

app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);

    // 统一处理所有WebSocket消息
    socket.on('message', (msg) => {
        console.log('Message received:', msg);
        socket.emit('response', 'Echo: ' + msg); // 向客户端发送响应
    });

    socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
    });
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

HTML页面

同时,我们需要一个HTML页面来测试WebSocket功能:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Test</title>
</head>
<body>
    <input type="text" id="messageInput" placeholder="Type a message...">
    <button onclick="sendMessage()">Send Message</button>

    <script src="/socket.io/socket.io.js"></script>
    <script>
        const socket = io();

        function sendMessage() {
            const message = document.getElementById('messageInput').value;
            socket.emit('message', message);
        }

        socket.on('response', (msg) => {
            alert(msg);
        });
    </script>
</body>
</html>

解释

  1. Express:用于处理HTTP请求。
  2. Socket.IO:用于处理WebSocket连接,并提供了简单的API来发送和接收消息。
  3. 统一路由:在这个例子中,所有的WebSocket消息都通过socket.on('message', ...)进行处理,这相当于一个统一的路由机制。

这种方式使得你可以在同一个项目中同时使用HTTP和WebSocket,而不需要为每种协议分别维护不同的路由逻辑。


Sails.js就是这样做的。

新建了一个sails应用 api有这几个目录 adapters controllers models policies services adapters policies services 这是干吗的 聊天的代码应该写在哪儿呢?

我用过Sails 0.9做开发,下面的信息供你参考。

1. adapter

/api/adapters目录下部署自定义的数据库适配器。常用的数据库,如MongoDB或者MySQL等,已经有对应的适配器实现,所以一般这里不需要有自己的代码文件。

2. policy

Policy是Sails的授权机制,定义了外部用户对controller的访问权限。例如,如果你正在开发Dropbox,在允许用户上载文件之前,你首先要确定用户是否已经得到认证(isAuthenticated),然后要确保他对文件夹有写的权限(canWrite),最后你还要保证目标文件夹有足够的空余空间(hasEnoughSpace)。

定义policy

所有policy都定义在api/policies文件夹下面,每个policy文件只包含一个函数。

本质上,policy也是一个Connect/Express中间件,不过它们在controller之前运行。可以定义多个policy,它们以链式方式工作——理想情况下,每个中间件就应该只完成一项功能。

例如,编写一个canWrite策略:

// policies/canWrite.js
module.exports = function canWrite (req, res, next) {
  var targetFolderId = req.param('id');
  var userId = req.session.user.id;

Permission .findOneByFolderId( targetFolderId ) .exec( function foundPermission (err, permission) {

// 有未预料的错误发生—— 跳到默认的错误处理器 (状态码:500)
if (err) return next(err);

// 用户无权操作这个文件夹。
// 这可能是因为文件夹被删除了,或者用户本来就没有权限,等等。
if ( ! permission ) return res.redirect('/notAllowed');

// 检查是否有写的权限
if ( permission.type !== 'write' ) return res.redirect('/notAllowed');

// 如果用户对目标文件夹拥有写的权限,那就继续执行后续的代码。
next();

}); };

使用policy

Sails的默认访问控制列表(Access Controller List, ACL)定义在config/policies.js,它的作用建立ACL和controller之间的映射。

config/policies.js的风格是声明式的。任何在api/policies下的文件,都可以在config/policies.js中直接引用。例如,api/policies/authenticated.jsconfig/policies.js中直接引用为authenticated

Sails的内置策略:

  • true - 公开访问。任何人都有权访问。
  • false - 禁止访问。任何人都不可以访问。

默认的访问控制列表是*: true,即任何人都有权访问任意的controller和action。正式发布时(production模式),应该设置为*: false,以免暴露应用逻辑。

添加策略示例

RabbitController: {
// RabbitController的所有action的默认策略是`false`,
// 即任何人都不无权访问。
'*': false,

// 对于`nurture`,应用'isRabbitMother'策略
// (这会覆盖上面的`false`策略)
nurture    : 'isRabbitMother',

// 只有满足`isNiceToAnimals` 和 `hasRabbitFood` 策略的用户,
// 才可以喂兔子
feed : ['isNiceToAnimals', 'hasRabbitFood']

}

其中的isNiceToAnimals策略,

// api/policies/isNiceToAnimals.js
module.exports = function isNiceToAnimals (req, res, next) {

    // `req.session` 包含了当前请求用户的历史数据。

    if ( req.session.user.hasHistoryOfAnimalCruelty ) {
        return res.redirect('http://PETA.org');
    }

    if ( req.session.user.frownsAtPuppies ) {
        return res.redirect('http://www.dailypuppy.com/');
    }

    // 如果用户的记录良好,
    // 继续下一策略验证,直到controller
    next();
};

3. Service

什么是service?

不确定:从0.10版开始?

本质上,service就是库,即在应用其它地方被多次调用的代码。例如,把电子邮件服务包装成一个EmailService,方便在其它代码中调用。

如何创建一个service?

仍然以EmailService为例,

// api/services/EmailService.js
exports.sendInviteEmail = function(options) {

var opts = {“type”:“messages”,“call”:“send”,“message”: { “subject”: “YourIn!”, “from_email”: “info@balderdash.co”, “from_name”: “AmazingStartupApp”, “to”:[ {“email”: options.email, “name”: options.name} ], “text”: “Dear “+options.name+”,\nYou’re in the Beta! Click <insert link> to verify your account” } };

myEmailSendingLibrary.send(opts); };

Sails会自动把service暴露给其它代码,

// 在controller中调用
EmailService.sendInviteEmail({email: 'test@test.com', name: 'test'});

Node.js 框架中集成 WebSocket 并使用统一路由的实现方案是存在的。一个流行的框架是 socket.io,它支持 WebSocket,并且可以与 Express 等常用 Web 框架一起工作。虽然它本身并不直接提供路由功能,但你可以通过 Express 的路由机制来实现统一的路由管理。

下面是一个简单的示例,展示如何在 Express 中集成 socket.io,并为 WebSocket 请求设置统一的路由处理:

示例代码

首先安装必要的依赖包:

npm install express socket.io

然后创建一个简单的 Express 应用程序,并集成 socket.io

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);

app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html');
});

// 使用统一的路由处理WebSocket连接
io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);

    // 统一处理消息
    socket.on('message', (data) => {
        console.log('Message received:', data);

        // 响应客户端
        socket.emit('response', { message: 'Hello from server!' });
    });

    // 断开连接时触发
    socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
    });
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. Express 集成:使用 Express 处理 HTTP 请求,同时为 WebSocket 创建一个独立的服务器。
  2. 统一路由:通过 io.on('connection') 监听 WebSocket 连接事件,并在该事件处理函数内部处理消息。
  3. 消息处理:通过 socket.on('message') 监听客户端发送的消息,并统一处理这些消息。响应时,也可以通过 socket.emit() 发送消息给客户端。

这种方法允许你在 Express 的路由系统之外,为 WebSocket 创建一个独立的路由处理逻辑。这样可以保持应用程序的整洁和模块化。

回到顶部