0

我似乎在browser-sync中使用的插座和我想用于socket.io的插座有冲突。我通过gulp任务(使用Aurelia CLI默认项目)使用browser-sync。会发生什么是只有browser-sync套接字似乎工作,并且主要用于服务器端的socket.io完全未读。我确实找到了解决该问题的GitHub issue #71,以及这两个都提到使用名称空间的其他Github issue #241。然而,我尝试了一些差异,即使它们运行有错误,但它不能解决我的任何问题。如何解决浏览器同步和socket.io冲突?

我主要使用Gulpbrowser-syncAurelia CLI项目中,而后端是NodeJSKoa。的[email protected][email protected]使用的端口的版本是前端:4000,后端:5000

这里的文件

咕嘟咕嘟的列表 - run.js

import gulp from 'gulp'; 
import browserSync from 'browser-sync'; 
import historyApiFallback from 'connect-history-api-fallback/lib'; 
import project from '../aurelia.json'; 
import build from './build'; 
import {CLIOptions} from 'aurelia-cli'; 
import url from 'url'; 
import proxy from 'proxy-middleware'; 

var portBackEnd = 5000; 
var portFrontEnd = 4000; 

var proxyOptionsAccessControl = function(req,res, next){ 
     res.setHeader('Access-Control-Allow-Origin', '*'); 
     next(); 
}; 

var proxyOptionsApiRoute = url.parse(`http://localhost:${portBackEnd}/api`); 
    proxyOptionsApiRoute.route = '/api'; 

var proxyOptionsAuthRoute = url.parse(`http://localhost:${portBackEnd}/auth`); 
    proxyOptionsAuthRoute.route = '/auth'; 

function log(message) { 
    console.log(message); //eslint-disable-line no-console 
} 

function onChange(path) { 
    log(`File Changed: ${path}`); 
} 

function reload(done) { 
    browserSync.reload(); 
    done(); 
} 

let serve = gulp.series(
    build, 
    done => { 
    browserSync({ 
     online: false, 
     open: false, 
     port: portFrontEnd, 
     notify: true, 
     logLevel: 'silent', 
     server: { 
     baseDir: ['.'], 
     middleware: [ 
      proxyOptionsAccessControl, 
      proxy(proxyOptionsApiRoute), 
      proxy(proxyOptionsAuthRoute) 
     ] 
     }, 
     socket: { 
     domain: 'localhost:4000', 
     namespace: '/browsersync' 
     } 
    }, function(err, bs) { 
     let urls = bs.options.get('urls').toJS(); 
     log(`Application Available At: ${urls.local}`); 
     log(`BrowserSync Available At: ${urls.ui}`); 
     done(); 
    }); 
    } 
); 

let refresh = gulp.series(
    build, 
    reload 
); 

let watch = function() { 
    gulp.watch(project.transpiler.source, refresh).on('change', onChange); 
    gulp.watch(project.markupProcessor.source, refresh).on('change', onChange); 
    gulp.watch(project.cssProcessor.source, refresh).on('change', onChange); 
}; 

let run; 

if (CLIOptions.hasFlag('watch')) { 
    run = gulp.series(
    serve, 
    watch 
); 
} else { 
    run = serve; 
} 

export default run; 

使用具有Aurelia的Socket.io客户端(前端)

import io from 'socket.io-client'; 

var socket = io('http://localhost:5000'); 
// also tried with a namespace instead 
//var socket = io('/todo-socket'); 

// ... 

socket.on("todo_update", data => { 
    let pos = arrayFindObjectIndex(this.items, 'id', data.id); 
    if(pos >= 0) { 
    this.items.splice(pos, 1, data); 
    this.itemDoneCount = this.items.filter(x => x.completed).length; 
    } 
}); 

用的NodeJS兴亚(后端)

// Middlewares 
const app = require('koa')(); 
const serve = require('koa-static'); 
const api = require('koa-router')(); 
const assertTimeout = require('co-assert-timeout'); 
const http = require('http'); 
const server = require('http').createServer(app.callback()); 
const io = require('socket.io')(server); 

// or without namespace: io.sockets.on("connection", function(socket) { 
var tsp = io.of('/todo-socket'); 
tsp.on("connection", function(socket) { 
    console.log('A new WebSocket client connected with ID: ' + socket.client.id); 
}) 
.error(function(err){ 
    console.log("Changefeeds Failure: ", err); 
    return null; 
}); 

socket.on('disconnect', function(data) { 
    console.log('A WebSocket client disconnnected with ID: ' +  socket.client.id); 
    return null; 
}); 

我想有和没有命名空间,这似乎并没有改变任何东西。我提到browser-sync - socket option

编辑

从测试这个多,它实际上好像在服务器端socket.io是不工作的。它不会从服务器输出console.log('connected with ID: ' + socket.client.id),但它不会显示或抛出任何错误。服务器端的代码与WebPack一起使用,所以我认为它与browserSync冲突有关。

回答

1

经过几天后,我得到了它的工作。我不得不在两个不同的地方,在browserSync选项和客户端(Aurelia)中更改命名空间,我使用另一个必须是不同命名空间的套接字。最后,必须使用io.of('/clientNamespace')调用NodeJS Koa

重要的注意,要知道,无论是browserSync和客户端命名空间必须与完整的URL声明:端口+命名空间(例如:http://localhost:4000/namespaceBs),在服务器端,命名空间仅与没有URL的名称一起使用(例如:/namespaceClient)。

如果你有没有想过,我把它叫做todoSocket因为它是一个TODO应用

因此使其短,我改变了下面的代码:

咕嘟咕嘟 - 运行。JS

let serve = gulp.series(
    build, 
    done => { 
    browserSync({ 
     online: false, 
     open: false, 
     port: portFrontEnd, 
     notify: true, 
     logLevel: 'silent', 
     server: { 
     baseDir: ['.'], 
     middleware: [ 
      proxyOptionsAccessControl, 
      proxy(proxyOptionsApiRoute), 
      proxy(proxyOptionsAuthRoute) 
     ] 
     }, 
     socket: { 
     namespace: `http://localhost:4000/bs` // <<<<HERE>>>> 
     } 
    }, function(err, bs) { 
     let urls = bs.options.get('urls').toJS(); 
     log(`Application Available At: ${urls.local}`); 
     log(`BrowserSync Available At: ${urls.ui}`); 
     done(); 
    }); 
    } 
); 

使用Socket.io客户端与奥里利亚(前端)

import io from 'socket.io-client'; 

var socket = io('http://localhost:5000/todo-socket'); // <<<<HERE>>>> 

用的NodeJS兴亚

const http = require('http'); 
const server = http.createServer(app.callback()); 
const io = require('socket.io')(server); 

// Load config for RethinkDB and koa 
const config = require("./config"); 

// attach on the todo-socket namespace, only the name (not the full URL) 
var todoSocket = io.of('/todo-socket');   // <<<<HERE>>>> 
todoSocket.on("connection", function(socket) { // <<<< AND HERE >>>> 
    console.log('A new TODO WebSocket namespace client connected with ID: ' + socket.client.id); 
});