[英]Node.js minimal function for parsing route
我有一個正在運行的Node.js / Express應用程序,它接收到的路由如下:
app.get('/resource/:res', someFunction);
app.get('/foo/bar/:id', someOtherFunction);
這很棒,效果很好。
我也在使用Socket.IO,並且希望有一些服務器調用使用websocket而不是傳統的RESTful調用。 但是,我想使其非常干凈,並且幾乎使用相同的語法,最好是:
app.sio.get('/resource/:res', someFunction);
這將為Socket.IO提供一個綜合的“ REST”接口,從程序員的角度來看,他在做什么上都沒有什么不同。 只是標記websockets: true
在客戶端為websockets: true
。
我可以處理所有細節,例如傳遞請求動詞並解析它們的自定義方式等等,所以我對此沒有問題。 我正在尋找的唯一的東西是一些函數,可以像Express一樣解析路由,並正確地路由它們。 例如,
// I don't know how to read the ':bar',
'foo/:bar'
// Or handle all complex routings, such as
'foo/:bar/and/:so/on'
我可以深入挖掘並嘗試自己編寫代碼,或者嘗試通讀所有express的源代碼並找到他們在哪里進行操作,但我確信它本身就存在。 只是不知道在哪里找到它。
robertklep提供了一個很好的答案,這對我來說完全解決了。 我將其調整為完整的解決方案,並將其發布在下面的答案中。
您可以使用Express路由器類來完成繁重的工作:
var io = require('socket.io').listen(...);
var express = require('express');
var sioRouter = new express.Router();
sioRouter.get('/foo/:bar', function(socket, params) {
socket.emit('response', 'hello from /foo/' + params.bar);
});
io.sockets.on('connection', function(socket) {
socket.on('GET', function(url) {
// see if sioRouter has a route for this url:
var route = sioRouter.match('GET', url);
// if so, call its (first) callback (the route handler):
if (route && route.callbacks.length) {
route.callbacks[0](socket, route.params);
}
});
});
// client-side
var socket = io.connect();
socket.emit('GET', '/foo/helloworld');
很明顯,您可以隨請求傳遞額外的數據,也可以將其傳遞給路由處理程序(例如,作為附加參數)。
robertklep提供了一個很好的答案,這對我來說完全解決了。 我將其調整為完整的解決方案,以防其他人想做類似的事情:
// Extend Express' Router to a simple name
app.sio = new express.Router();
app.sio.socketio = require('socket.io').listen(server, { log: false });
// Map all sockets requests to HTTP verbs, which parse
// the request and pass it into a simple callback.
app.sio.socketio.sockets.on('connection', function (socket) {
var verbs = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
for (var i = 0; i < verbs.length; ++i) {
var go = function(verb) {
socket.on(verb, function (url, data) {
var route = app.sio.match(verb, url);
if (route && route.callbacks.length) {
var req = {url: url, params: route.params, data: data, socket:socket}
route.callbacks[0](req);
}
});
}(verbs[i]);
}
});
// Simplify Socket.IO's 'emit' function and liken
// it traditional Express routing.
app.sio.end = function(req, res) {
req.socket.emit('response', req.url, res);
}
// Here's an example of a simplified request now, which
// looks nearly just like a traditional Express request.
app.sio.get('/foo/:bar', function(req) {
app.sio.end(req, 'You said schnazzy was ' + req.data.schnazzy);
});
// Instantiate Socket.IO
var socket = io.connect('http://xxxxxx');
socket.callbacks = {};
// Similar to the server side, map functions
// for each 'HTTP verb' request and handle the details.
var verbs = ['get', 'post', 'put', 'path', 'delete'];
for (var i = 0; i < verbs.length; ++i) {
var go = function(verb) {
socket[verb] = function(url, data, cb) {
socket.emit(String(verb).toUpperCase(), url, data);
if (cb !== undefined) {
socket.callbacks[url] = cb;
}
}
}(verbs[i]);
}
// All server responses funnel to this function,
// which properly routes the data to the correct
// callback function declared in the original request.
socket.on('response', function (url, data) {
if (socket.callbacks[url] != undefined) {
socket.callbacks[url](data);
}
});
// Implementation example, params are:
// 1. 'REST' URL,
// 2. Data passed along,
// 3. Callback function that will trigger
// every time this particular request URL
// gets a response.
socket.get('/foo/bar', { schnazzy: true }, function(data){
console.log(data); // -> 'You said schnazzy was true'
});
感謝您的幫助,robertklep!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.