WebSocket 연결 실패:WebSocket 핸드쉐이크 중 오류 발생:예기치 않은 응답 코드: 400
Socket.io을 Angular와 통합하려고 하는데 클라이언트 측에서 서버로의 접속에 어려움을 겪고 있습니다.관련된 다른 질문들을 살펴보았지만, 제 문제는 로컬에서 발생하고 있기 때문에 중간에 웹 서버가 없습니다.
서버 코드는 다음과 같습니다.
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 서버 프로세스를 재시작하면 메시지를 보낼 수 있지만 웹소켓 대신 폴링을 사용한다는 것입니다.
socket.connect 호출로 여러 가지 옵션을 시도해 봤지만 아무 소용이 없었습니다.
어떤 도움이라도 주시면 감사하겠습니다.
업데이트 (2016년 12월 30일) :
웹소켓이 부분적으로 작동하고 있다는 것을 방금 알았습니다.Chrome 개발자 콘솔에 101 Switching Protocols 요청이 표시됩니다.다만, 표시되는 프레임은 engine.io 의 프로토콜 패킷(ping, pong) 뿐입니다.단, 어플리케이션소켓 메시지는 어떤 이유로 폴링에 반환됩니다.
문제 해결!저는 방금 문제를 해결하는 방법을 알아냈지만, 이것이 정상적인 행동인지 알고 싶습니다.
(101 스위칭 프로토콜 요청으로 표시됨) 웹 소켓 연결이 올바르게 설정되더라도 기본값이 롱 폴링인 것으로 보입니다.이 수정은 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, Node 서버 및 Angular 4에서 작동했습니다.
nginx 웹 서버 구성 파일을 다음과 같이 편집합니다.
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";
}
현재 받아들여지고 있는 솔루션은 오해를 불러일으키고 있습니다.
공식 설명서에 따르면,transports: [ 'websocket' ]
옵션을 사용하면 웹 소켓 연결을 확립할 수 없을 때 롱 소켓으로 폴백하는 기능을 효과적으로 제거할 수 있습니다., 「」가 됩니다.socket.io
많은 시나리오에 적응할 수 있기 때문에 애초에 매우 강력합니다.
특히 웹소켓에만 의존하는 경우에는 를 직접 사용하는 것이 좋습니다.
그 외의 경우(대부분의 유저로 추정)에서는, 이것은 역프록시/서버 설정의 문제일 가능성이 높습니다.
공식 문서에서는 환경에 따라 다음 사항을 제안합니다.
NginX 설정
http {
server {
listen 3000;
server_name io.yourhost.com;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://nodes;
# enable WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
upstream nodes {
# enable sticky session based on IP
ip_hash;
server app01:3000;
server app02:3000;
server app03:3000;
}
}
Apache HTTPD 구성
Header add Set-Cookie "SERVERID=sticky.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy "balancer://nodes_polling">
BalancerMember "http://app01:3000" route=app01
BalancerMember "http://app02:3000" route=app02
BalancerMember "http://app03:3000" route=app03
ProxySet stickysession=SERVERID
</Proxy>
<Proxy "balancer://nodes_ws">
BalancerMember "ws://app01:3000" route=app01
BalancerMember "ws://app02:3000" route=app02
BalancerMember "ws://app03:3000" route=app03
ProxySet stickysession=SERVERID
</Proxy>
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) balancer://nodes_ws/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) balancer://nodes_polling/$1 [P,L]
ProxyTimeout 3
HAProxy 설정
listen chat
bind *:80
default_backend nodes
backend nodes
option httpchk HEAD /health
http-check expect status 200
cookie io prefix indirect nocache # using the `io` cookie set upon handshake
server app01 app01:3000 check cookie app01
server app02 app02:3000 check cookie app02
server app03 app03:3000 check cookie app03
HAProxy의 접속 업그레이드에서도 읽을 수 있습니다.
자세한 내용은 위의 공식 문서 링크를 참조하십시오.
편집:
바니시(출처: 여기)
sub vcl_recv {
if (req.http.upgrade ~ "(?i)websocket") {
return (pipe);
}
}
sub vcl_pipe {
if (req.http.upgrade) {
set bereq.http.upgrade = req.http.upgrade;
set bereq.http.connection = req.http.connection;
}
}
이 문제를 해결하기 위해 트랜스포트를 '웹소켓'에서 '폴링'으로 변경했습니다.
var socket = io.connect('xxx.xxx.xxx.xxx:8000', {
transports: ['polling']
});
소켓을 통해 보내는 메시지로 판단하건대. ★★★★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
다음 중 하나를 수행할 수 있습니다.
- 모듈을 분리합니다.
io 및를 socket.io로 합니다.
websocket
를 했을 때expressStatusMonitor
다음과 같이 합니다.const server = require('http').Server(app); const io = require('socket.io')(server); ... app.use(expressStatusMonitor({ websocket: io, port: app.get('port') }));
같은 문제였지만 내 앱은 nginx보다 늦었다.Nginx 설정을 변경함으로써 오류가 삭제되었습니다.
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
저는 같은 문제에 직면하여 apache2 가상 호스트 Entery를 개량하여 성공을 거두었습니다.
주의: 서버에서는 9001 포트로 문제없이 정상적으로 설치 및 동작하고 있습니다.이 apache2 전용 가이드라인은 nginx와 관계가 없습니다.이 답변은 apache2+etherpad 애호가에게만 해당됩니다.
<VirtualHost *:80>
ServerName pad.tejastank.com
ServerAlias pad.tejastank.com
ServerAdmin snippetbucket@gmail.com
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의 모든 모드를 활성화하십시오.
apache2 를 재기동합니다.하지만 사이트를 활성화하려면 명백한 a2ensite가 필요합니다.
""를 .http
이 좋을 것 .ws
이치노 써보세요.ws://localhost:3000
사용할 수 있습니다.
는 네가 의 이름을 해.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');
이 에러를 해소하기 위해서 express-status-monitor 를 인스톨 했을 뿐입니다.
다음은 설정입니다.
install express-status-monitor
npm i express-status-monitor --save
const expressStatusMonitor = require('express-status-monitor');
app.use(expressStatusMonitor({
websocket: io,
port: app.get('port')
}));
는, 하지 않은 입니다.process.env.PORT
Heroku와 다른 서비스들이 사용하는 임의의 포트 번호를 적절하게 처리하기 때문에 매우 중요합니다.
그래서 그것이 나에게 효과가 있는 코드입니다.
var app = require('express')();
var http = require('http').createServer(app);
const serverPort = process.env.PORT ; //<----- important
const io = require('socket.io')(http,{
cors: {
origin: '*',
methods: 'GET,PUT,POST,DELETE,OPTIONS'.split(','),
credentials: true
}
});
http.listen(serverPort,()=>{
console.log(`server listening on port ${serverPort}`)
})
node.witk socket.io 에서 같은 에러가 발생했지만, 그 이유는 매우 어리석었습니다.socket.io의 모든 종속성이 올바르게 설치되어 있지 않습니다.즉, 패키지 base64id가 누락되었습니다.
클라이언트 측에서 포트 3000을 사용하고 있습니다.서버 포트가 아니라 앵귤러 포트인 것 같은데?서버 포트에 연결되어 있어야 합니다.
다음 로드 밸런서 설정을 사용해도 특정 ISP에 대해 wss에 대해 문제가 해결되었지만 ws에 대해서는 문제가 여전히 존재합니다.
이 문제를 해결하려면io.listen(server);
passport.socketio를 통합하고 여권 미들웨어를 사용할 때 이 오류가 발생하기 시작했습니다.
httpd/http를 사용하는 경우 ws.conf와 같은 파일을 추가하여 이 코드를 추가할 수 있습니다.또, 이 솔루션에서는, 「http://localhost:6001/socket.io」와 같은 것을 「http://localhost/socket.io」에 프록시 할 수 있습니다.
<VirtualHost *:80>
RewriteEngine on
#redirect WebSocket
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:6001/$1 [P,L]
ProxyPass /socket.io http://localhost:6001/socket.io
ProxyPassReverse /socket.io http://localhost:6001/socket.io
</VirtualHost>
Apollo Server 2 사용.
https://github.com/apollographql/apollo-client/issues/4778#issuecomment-509638071,에 따르면, 이것으로 문제가 해결되었습니다.
'ws://localhost:syslog/graphql' 시도
...착신 요구와 발신 요구가 같은 주소를 사용하게 되었기 때문입니다.
나의 문제는 서버 쪽이었다.
const app = require("express")();
const http = require("http").Server(app);
const io = require("socket.io")(http);
귀를 기울이다
http.listen(PORT,()=> console.log('listening'))
내가 했을 때 그것은 나에게 오류를 주었다.
app.listen(......)
포함하여transports: ['websocket']
는, 어떠한 시나리오에서도 Sockt.io 의 기능을 배제하기 때문에, 최적인 어프로치는 아닙니다.
Nodejs + Nginx + Vuejs / Vite ( Front )를 사용하는 경우 Nginx 사이트 설정에서 리버스 프록시를 설정하여 해결할 수 있었습니다.
http {
server {
listen 80;
root /var/www/html;
// <---- start ---->
location /socket.io/ { // <--- Set your custom path
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://localhost:3000; // <--- Set your Port
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
// <---- End ---->
}
}
이 문제에 대한 참고 자료는 Socket.io 웹사이트 또는 Nginx에서 찾을 수 있습니다.
위의 모든 옵션을 시도했다면 코드에는 문제가 없습니다.브라우저의 애드 블로커를 정지해 주세요.그것은 나에게 효과가 있었다.
블로커를 비활성화한 후 마이 출력 산출량
내 서버 서버
언급URL : https://stackoverflow.com/questions/41381444/websocket-connection-failed-error-during-websocket-handshake-unexpected-respon
'programing' 카테고리의 다른 글
React-Query 훅을 사용한 조건부 API 호출 (0) | 2023.03.21 |
---|---|
단순한 어레이 초기화를 사용한ng-timeout (0) | 2023.03.21 |
두 날짜 사이의 객체 찾기 MongoDB (0) | 2023.03.21 |
사용자가 필드를 떠난 후 필드 확인 (0) | 2023.03.21 |
Angular가 있는 듀얼 목록 상자 찾기JS 및 부트스트랩 (0) | 2023.03.21 |