所以我在设置socket.io时遇到问题。 我有一个具有快速路由和MSGraph授权的Loopback 3服务器和一个Angular 9客户端。
我在Angular 9中使用socket.io服务器端和socket.io-client。
我以前可以使它工作,但是由于某种原因它已经坏了,我不知道如何解决它。
所以我想实现的是设备激活系统。客户端A显示类似“ 52sdf5”的代码,客户端B在仪表板上输入代码。这两部分都在1个应用程序内,只是路径不同。
因此在服务器端,server.js文件中包含以下内容:
'use strict';
var loopback = require('loopback');
var boot = require('loopback-boot');
var app = module.exports = loopback();
app.start = function() {
// start the web server
return app.listen(function() {
app.emit('started');
var baseUrl = app.get('url').replace(/\/$/, '');
console.log('Web server listening at: %s', baseUrl);
if (app.get('loopback-component-explorer')) {
var explorerPath = app.get('loopback-component-explorer').mountPath;
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
}
});
};
// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
if (err) throw err;
// start the server if `$ node server.js`
if (require.main === module) {
app.io = require('socket.io')(app.start());
// Also tried the following but didn't work:
// app.io = require('socket.io')(app.start(), { origins: '*:*' });
app.io.on('connection', (socket) => {
console.log('a user connected');
socket.on("device", (code) => {
console.log("device");
console.log(code);
socket.join(code);
});
socket.on('activateCode', (code, name, companyId) => {
console.log("activated code");
console.log(code);
console.log(name);
socket.join(code);
socket.broadcast.to(code).emit('activate', name, companyId);
});
socket.on('deviceActivated', (code, err, res) => {
socket.broadcast.to(code).emit('activated', code, err, res);
socket.leave(code);
});
socket.on('activationFinished', (code) => {
socket.leave(code);
})
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
}
});
对于客户端,有3个与socket.io相关的部分:
首先,我有一个应用程序模型,其中存储了通用数据以供使用。
两个客户端(A和B,请参见上面的示例)都将其用于其套接字:
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
import { AuthUser } from './vo/auth-user';
import { Building } from './vo/building';
import { Group } from './vo/group';
import { Room } from './vo/room';
import { Device } from './vo/device';
import * as socketIo from 'socket.io-client';
import { Company } from './vo/company';
@Injectable({
providedIn: 'root'
})
export class ApplicationModel {
private _messageError: Subject<string> = new Subject<string>();
private _isLoggedIn: boolean;
private _activeUser: AuthUser;
private _activeCompany: Company;
private _locale: string;
private _socket: socketIo.Server = socketIo('http://localhost:3001/');
private _currentRoom: Room;
private _currentBuilding: Building;
private _currentGroup: Group;
private _currentDevice: Device;
private _currentTemplate: string;
constructor() {
}
get socket(): socketIo.Server {
return this._socket;
}
/* and a bunch of other methods like setters and getters for the other properties*/
}
所以对于激活码,我有:
ngOnInit() {
//this.socket = this.apm.socket;
console.log(Math.random().toString(36));
this.code = Math.random().toString(36).substring(2, 5) + Math.random().toString(36).substring(2, 5);
this.deviceInfo = this.deviceService.getDeviceInfo();
console.log(window);
console.log(this.deviceInfo.os);
console.log(this.apm.socket.connected);
this.ds.getIp().subscribe((data: { ip: string }) => {
this.ip = data.ip;
this.apm.socket.emit("device", this.code);
this.apm.socket.on('activate', (name, companyId) => {
console.log(companyId);
console.log(name);
let device: Device = {
name: name,
os: this.deviceInfo.os,
ip: this.ip
}
this.ds.createDevice(companyId, device).subscribe((dev: Device) => {
let device = dev;
device.companyId = companyId;
this.as.setDeviceCookie(device);
this.apm.socket.emit("deviceActivated", this.code, null, dev.id);
console.log(this.apm.currentTemplate);
this.router.navigate([this.apm.currentTemplate]);
}, (err) => {
this.apm.socket.emit("deviceActivated", this.code, err, null);
});
});
console.log(this.apm.socket.connected);
}, (err) => {
console.log(err);
});
}
因此,通常在可见代码时,用户可以转到仪表板并输入代码和相应的名称。因此,当用户提交将其发送到后端服务器的代码时:
onSubmit() {
this.isBusy = true;
this.hasActivationError = false;
console.log(this.code);
console.log(this.name);
this.apm.socket.emit('activateCode', this.code, this.name, this.apm.activeUser.companyId);
this.apm.socket.on('activated', (code, err, res) => {
if (err) {
this.apm.messageErrorChange("There was an error while activating the device.");
console.log(err);
this.hasActivationError = true;
this.isBusy = false;
} else {
this.apm.currentDevice = res;
this.isBusy = false;
this.apm.socket.emit('activationFinished', code);
this.router.navigate(['manage', 'devices', 'details']);
}
});
}
成功后,它将与具有该代码的相应客户端连接,然后应激活该客户端(现在永远永久,但以后将受到限制)。
因此,由于Web服务器从localhost:3001启动,因此通常传递给服务器的地址应该可以。但是由于某种原因,它总是让我在chrome中拒绝连接,并且在Firefox中CORS请求阻止了错误(具有以下链接:localhost:3001 / socket.io /?EIO = 3&transport = polling&t = NATx-e1)。
如果有人知道问题可能是什么或如何解决此问题,请让我知道是否需要更多信息。
预先感谢。
PS:这是在ubuntu的Digitalocean上,我正在使用Nginx为网站和后端提供SSL证书。