Socket.ioをAngularと統合しようとしていますが、クライアント側からサーバーへの接続に問題があります。他の関連する質問に目を通しましたが、私の問題はローカルで発生しているため、途中にWebサーバーはありません。
これは私のサーバーコードのようです:
const app = express();
const server = http.createServer(app);
const io = require('socket.io').listen(server);
io.on('connection', function(socket) {
socket.emit('greet', { hello: 'Hey, Mr.Client!' });
socket.on('respond', function(data) {
console.log(data);
});
socket.on('disconnect', function() {
console.log('Socket disconnected');
});
});
Gruntを使用して、次の順序でクライアント側のJavaScriptファイルをロードしています。
dist: {
src: [
public/bower_components/angular/angular.min.js,
...
public/bower_components/socket.io-client/dist/socket.io.min.js,
public/bower_components/angular-socket-io/socket.min.js,
...
]
}
次に、私のコントローラーで:
function MyController($scope) {
let socket = io.connect(window.location.href);
socket.connect('http://localhost:3000');
socket.on('greet', function(data) {
console.log(data);
socket.emit('respond', { message: 'Hello to you too, Mr.Server!' });
});
...
}
btford/angular-socket-io
ライブラリを実際に使用する前に、正しく接続できることを確認したいのですが、コンソールに次のエラーが表示されます。
興味深いのは、Node.jsサーバープロセスを再起動すると、websocketの代わりにポーリングを使用してメッセージを送信できることです。
Socket.connect呼び出しでさまざまなオプションを試しましたが、何も機能しませんでした。
任意の助けをいただければ幸いです。
Websocketが部分的に機能していることに気付きました。 Chrome開発者コンソールに101スイッチングプロトコルリクエストが表示されます。ただし、表示されるフレームはengine.ioプロトコルパケット(ping、pong)のみです。ただし、アプリケーションソケットメッセージは、何らかの理由でまだポーリングにフォールバックしています...
問題が解決しました!私は問題を解決する方法を考え出しましたが、これが通常の動作であるかどうかを知りたいです。
(101 Switching Protocolsリクエストで示される)Websocket接続が正しく確立されたとしても、デフォルトではロングポーリングが行われているようです。修正は、このオプションをSocket.io接続関数に追加するのと同じくらい簡単でした。
{transports: ['websocket']}
したがって、コードは最終的に次のようになります。
const app = express();
const server = http.createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket) {
console.log('connected socket!');
socket.on('greet', function(data) {
console.log(data);
socket.emit('respond', { hello: 'Hey, Mr.Client!' });
});
socket.on('disconnect', function() {
console.log('Socket disconnected');
});
});
そしてクライアントで:
var socket = io('ws://localhost:3000', {transports: ['websocket']});
socket.on('connect', function () {
console.log('connected!');
socket.emit('greet', { message: 'Hello Mr.Server!' });
});
socket.on('respond', function (data) {
console.log(data);
});
メッセージはフレームとして表示されます:
この Githubの問題 は正しい方向を示してくれました。手伝ってくれたみんなに感謝します!
Nginx Webサーバーの設定ファイルを次のように編集します。
server {
listen 80;
server_name 52.xx.xxx.xx;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_Host;
proxy_pass "http://127.0.0.1:4200";
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Socket.IO socket.emit('greet', { hello: 'Hey, Mr.Client!' });
を介して送信するメッセージから判断すると、hackathon-starter
ボイラープレートを使用しているようです。その場合、問題は次のようにexpress-status-monitor
モジュールが独自のsocket.ioインスタンスを作成している可能性があります。 https://github.com/RafalWilinski/express-status-monitor#using-module- with-socketio-in-project
次のいずれかを実行できます。
次のようにwebsocket
インスタンスを作成するときに、socket.ioインスタンスとポートをexpressStatusMonitor
として渡します。
const server = require('http').Server(app);
const io = require('socket.io')(server);
...
app.use(expressStatusMonitor({ websocket: io, port: app.get('port') }));
トランスポートを「websocket」から「polling」に変更することでこれを解決しました
var socket = io.connect('xxx.xxx.xxx.xxx:8000', {
transports: ['polling']
});
私は同じ問題に直面していましたが、Apache2バーチャルホストを改良して成功しました。
注:サーバーに問題なくインストールされ、9001ポートで正常に動作していました。 Apache2のこのガイドラインは、nginxとの関係はありません。Apache2+ etherpadの愛好家向けの回答です。
<VirtualHost *:80>
ServerName pad.tejastank.com
ServerAlias pad.tejastank.com
ServerAdmin [email protected]
LoadModule proxy_module /usr/lib/Apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/Apache2/modules/mod_proxy_http.so
LoadModule headers_module /usr/lib/Apache2/modules/mod_headers.so
LoadModule deflate_module /usr/lib/Apache2/modules/mod_deflate.so
ProxyVia On
ProxyRequests Off
ProxyPreserveHost on
<Location />
ProxyPass http://localhost:9001/ retry=0 timeout=30
ProxyPassReverse http://localhost:9001/
</Location>
<Location /socket.io>
# This is needed to handle the websocket transport through the proxy, since
# etherpad does not use a specific sub-folder, such as /ws/ to handle this kind of traffic.
# Taken from https://github.com/ether/etherpad-lite/issues/2318#issuecomment-63548542
# Thanks to beaugunderson for the semantics
RewriteEngine On
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:9001/socket.io/$1 [P,L]
ProxyPass http://localhost:9001/socket.io retry=0 timeout=30
ProxyPassReverse http://localhost:9001/socket.io
</Location>
<Proxy *>
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Proxy>
</VirtualHost>
高度なヒント:a2enmodの助けを借りてApache2のすべてのmodを有効にしてください
Apache2を再起動すると、効果が得られます。ただし、必要なサイトを有効にするa2ensiteは明らかです。
io.listen(server);
を削除することでこれを解決しました。 passport.socketioの統合とパスポートミドルウェアの使用を開始したときに、このエラーが発生し始めました。
次のようにクライアント側のorigins
を定義する必要があると思います。
//server.js
const socket = require('socket.io');
const app = require('express')();
const server = app.listen('port');
const io = socket().attach(server);
io.origins("your_domain:port www.your_domain:port your_IP:port your_domain:*")
io.on('connection', (socket) => {
console.log('connected a new client');
});
//client.js
var socket = io('ws://:port');
クライアント側でポート3000を使用しています。サーバーポートではなくAngularポートであると推測して危険です。サーバーポートに接続する必要があります。
コントローラーでは、http
スキームを使用していますが、websocketを使用しているので、ws
スキームを使用する必要があります。接続関数でws://localhost:3000
を使用してみてください。
次のロードバランサーの設定を使用した後、WSSの問題は解決しましたが、WSの問題は特定の1つのISPに引き続き存在します。