0

我似乎在使用的套接字browser-sync和我想使用的套接字之间存在冲突socket.io。我browser-sync通过一个任务(默认项目gulp附带)使用。Aurelia CLI发生的情况是只有browser-sync套接字似乎工作,socket.io而主要用于服务器端的套接字完全未读。我确实找到了解决该问题的GitHub 问题 #71,以及另一个Github 问题 #241,它们都提到了名称空间的使用。但是我尝试了一些差异,即使它们运行时出错,它也不能解决我的任何问题。

我主要在项目内部使用Gulpwith ,而后端是with 。while的版本使用的端口是前端:4000,后端:5000。browser-syncAurelia CLINodeJSKoasocket.io@1.6.0browser-sync@2.13.0

这是文件列表

Gulp - 运行.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;

将 Socket.io-Client 与 Aurelia 一起使用(前端)

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

带有 Koa 的 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;
});

我尝试了有无命名空间,这似乎并没有改变任何东西。我提到了浏览器同步 - 套接字选项

编辑

通过对此进行更多测试,实际上似乎socket.io服务器端根本不起作用。它不会console.log('connected with ID: ' + socket.client.id)从服务器输出,但也不会显示或抛出任何错误。服务器端的代码曾经使用过WebPack,所以我真的认为它与browserSync冲突有关。

4

2 回答 2

1

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

重要说明,请注意必须使用完整的 URL:port+namespace (ex.:) 声明thebrowserSync和 client 命名空间,在服务器端,命名空间仅与没有 URL 的名称一起使用(例如。 : )。http://localhost:4000/namespaceBs/namespaceClient

如果你想知道,我之所以称之为它todoSocket是因为它是一个 TODO 应用程序

因此,为了简短起见,我更改了以下代码:

Gulp - 运行.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-Client 与 Aurelia 一起使用(前端)

import io from 'socket.io-client';

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

带有 Koa 的 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);
});
于 2016-12-04T01:24:50.117 回答
1

对于在这篇文章中发生的其他任何人,以上内容对他们不起作用。我已经proxy像这样在我的配置中设置了

proxy: {
  target: `${protocol}://localhost:${SERVER__PORT}`,        
},

最终使两个套接字一起工作的修复方法只是添加ws

proxy: {
  target: `${protocol}://localhost:${SERVER__PORT}`,
  ws: true,
},
于 2020-10-09T21:35:02.783 回答