웹소켓:죽은 후 자동으로 다시 연결하는 방법
var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function () {
ws.send(JSON.stringify({
.... some message the I must send when I connect ....
}));
};
ws.onmessage = function (e) {
console.log('Got a message')
console.log(e.data);
};
ws.onclose = function(e) {
console.log('socket closed try again');
}
ws.onerror = function(err) {
console.error(err)
};
처음 소켓에 접속할 때는 먼저 서버에 메시지를 보내 본인 인증과 채널 가입을 해야 합니다.
내가 가진 문제는 소켓 서버가 때때로 신뢰할 수 없다는 것과 그것이 유발한다는 것입니다.onerror
그리고.onclose
의 사건들'ws'
물건.
질문:.소켓이 닫히거나 오류가 발생할 때마다 10초 동안 기다렸다가 소켓 서버에 다시 연결할 수 있는 좋은 설계 패턴은 무엇입니까(그리고 처음 메시지를 서버에 다시 전송).
이것이 제가 얻은 결과입니다.그것은 제 목적에 맞게 작동합니다.
function connect() {
var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function() {
// subscribe to some channels
ws.send(JSON.stringify({
//.... some message the I must send when I connect ....
}));
};
ws.onmessage = function(e) {
console.log('Message:', e.data);
};
ws.onclose = function(e) {
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
setTimeout(function() {
connect();
}, 1000);
};
ws.onerror = function(err) {
console.error('Socket encountered error: ', err.message, 'Closing socket');
ws.close();
};
}
connect();
이것은 나에게 효과가 있었습니다.setInterval
, 클라이언트 연결이 끊어질 수 있기 때문입니다.
ngOnInit(): void {
if (window.location.protocol.includes('https')) {
this.protocol = 'wss';
}
this.listenChanges();
}
listenChanges(): void {
this.socket = new WebSocket(`${this.protocol}://${window.location.host}/v1.0/your/url`);
this.socket.onmessage = (event): void => {
// your subscription stuff
this.store.dispatch(someAction);
};
this.socket.onerror = (): void => {
this.socket.close();
};
this.socket.onopen = (): void => {
clearInterval(this.timerId);
this.socket.onclose = (): void => {
this.timerId = setInterval(() => {
this.listenChanges();
}, 10000);
};
};
}
잊지말고 전화해요.clearInterval
소켓이 열렸을 때.
이는 명확하게 반응형 질문은 아니지만, 다음은 반응형 답변입니다.
TLDR: 사용할 수 있습니다.setInterval
웹소켓 연결 상태를 주기적으로 확인하고 연결이 종료된 경우 재연결을 시도합니다.https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState
class TestComponent extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.connect = this.connect.bind(this);
}
componentDidMount() {
this.interval = setInterval(this.connect, 1000);
}
componentWillUnmount() {
if (this.ws) this.ws.close();
if (this.interval) clearInterval(this.interval);
}
connect() {
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState
if (this.ws === undefined || (this.ws && this.ws.readyState === 3)) {
this.ws = new WebSocket(`ws://localhost:8080`);
this.ws.onmessage = (e) => {
console.log(JSON.parse(e.data));
};
}
}
render() {
return <div>Hey!</div>;
}
}
저는 이 패키지 https://github.com/pladaria/reconnecting-websocket 가 웹소켓 연결에 대한 재연결 문제를 해결할 수 있다는 것을 알았습니다.그리고 설정 가능한 옵션 목록을 가지고 있는데, 그 중 하나는reconnectionDelayGrowFactor
이것은 재접속 지연이 얼마나 빨리 증가하는지를 결정합니다.
소켓이 닫히거나 서버에 오류가 발생한 경우 비동기식 await를 사용하여 클라이언트가 5초마다 자동으로 연결을 시도합니다. 내 답변을 보십시오.
업데이트된 답변:
결국, (자바를 사용하지 않는 경우) 독자적인 "ping/pong" 전략을 구현하는 것이 좋다는 것을 알았습니다.(java를 사용하는 경우 ping/pong "action type"을 확인하십시오. 기억이 잘 나지 않습니다...)
- 클라이언트가 5초마다 "ping"을 서버로 전송했습니다.
- 서버가 "ping"을 받으면 클라이언트에 "pong"를 반향해야 합니다.
- 클라이언트가 5초 안에 "pong"를 수신하지 못하면 서버를 다시 연결해야 합니다.
제삼자의 입에 의지하지 마세요.
경고: 다음 도구를 사용하지 마십시오. (이유: 신뢰할 수 없고 안정적이지 않으며 매우 제한적으로 작동합니다.)
- 네트워크를 사용할 수 있는지 확인합니다. https://github.com/hubspot/offline
- 다시 연결하려면: https://github.com/joewalnes/reconnecting-websocket
저는 지난 몇 주 동안 이 문제로 어려움을 겪었고, 누군가에게 도움이 될 경우를 대비해 슈퍼소켓이라는 패키지를 만들기로 결정했습니다!이것은 네이티브 웹소켓을 대체하는 역할을 해야 합니다.제가 찾은 기존 패키지는 유지보수되지 않은 것 같습니다.
SuperSocket은 기존 WebSocket 구현의 맨 위에 있으며, 다른 기능들 중에서도 성공적으로 구현될 때까지 다시 연결해야 합니다.물론 무한 루프 및 불필요한 CPU 로드를 피하기 위해 최대 재시도를 설정할 수 있습니다. :)
//native implementation
var ws = new WebSocket('ws://localhost:8080');
//drop in replacement, embedding reconnect strategies
var ws = new SuperSocket('ws://localhost:8080');
웹소켓 재연결은 자동으로 재연결되는 API 호환 장식된 웹소켓 클래스를 제공하여 이 문제를 해결하는 작은 라이브러리입니다.
스크립트를 페이지에 추가합니다(예: a를 통해).<script>
tag) 및 위 링크된 README에 의해 설명된 바와 같이:
API 호환이 가능하므로 다음을 수행할 수 있습니다.
var ws = new WebSocket('ws://....');
다음으로 대체할 수 있습니다.
var ws = new ReconnectingWebSocket('ws://....');
시도해 보기:
const observable = Observable.create(
(obs: Observer<MessageEvent>) => {
this.ws.onmessage = obs.next.bind(obs);
this.ws.onerror = obs.error.bind(obs);
// this.ws.onclose = obs.complete.bind(obs);
this.ws.onclose = function () {
window.location.reload()
}
return this.ws.close.bind(this.ws);
});
const observer = {
next: (data: Object) => {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(data));
}
}
};
구성요소
getDatas() {
let url = environment.apiwebsocket
this.webSocketService.connect(url)
.subscribe(evt => {
let jsonObj = JSON.parse(evt.data)
});}
전에 이걸 프로젝트 어딘가에 뒀었어요
let rc = new WebSocket(
'ws://'
+ window.location.host
+ `/ws/chat/${window.seen.pk}/`
)
이제 다음으로 전환했습니다.
// ws create the websocket and returns it
function autoReconnect(ws_create){
let ws = ws_create();
function startReconnecting(){
let interval = setInterval(()=>{
console.log('trying')
ws = ws_create();
ws.onopen = () => {
console.log('stop');
ws.onclose = startReconnecting;
clearInterval(interval);
}
}, 3000);
}
ws.onclose = startReconnecting;
}
let rc;
autoReconnect(()=>{
rc = new WebSocket(
'ws://'
+ window.location.host
+ `/ws/chat/${window.seen.pk}/`
)
return rc;
});
실행 및 로컬 호스트 중지를 통해 테스트합니다. 잘 작동합니다. (btw 이 질문은 오랫동안 게시되었지만 짧고 우아한 해결책이 없습니다.)
이 방법의 장점은 화살표 함수를 전달하여 외부 범위에 변수를 할당할 수 있다는 것입니다.
여기 제 프로젝트에서 사용하는 간단한 버전이 있습니다.여기에는 재연결을 위한 증분 대기 타이머가 포함되어 있습니다.
//wsURL - the string URL of the websocket
//waitTimer - the incrementing clock to use if no connection made
//waitSeed - used to reset the waitTimer back to default on a successful connection
//multiplier - how quickly you want the timer to grow on each unsuccessful connection attempt
const openSocket = (wsURL, waitTimer, waitSeed, multiplier) =>{
let ws = new WebSocket(wsURL);
console.log(`trying to connect to: ${ws.url}`);
ws.onopen = () => {
console.log(`connection open to: ${ws.url}`);
waitTimer = waitSeed; //reset the waitTimer if the connection is made
ws.onclose = () => {
console.log(`connection closed to: ${ws.url}`);
openSocket(ws.url, waitTimer, waitSeed, multiplier);
};
ws.onmessage = (message) => {
//do something with messge...
};
};
ws.onerror = () => {
//increaese the wait timer if not connected, but stop at a max of 2n-1 the check time
if(waitTimer < 60000) waitTimer = waitTimer * multiplier;
console.log(`error opening connection ${ws.url}, next attemp in : ${waitTimer/1000} seconds`);
setTimeout(()=>{openSocket(ws.url, waitTimer, waitSeed, multiplier)}, waitTimer);
}
}
openSocket(`ws://localhost:3000`, 1000, 1000, 2)
언급URL : https://stackoverflow.com/questions/22431751/websocket-how-to-automatically-reconnect-after-it-dies
'bestsource' 카테고리의 다른 글
모달 창 내 트위터 부트스트랩 데이트피커 (0) | 2023.10.31 |
---|---|
Oracle: 스키마 간에 보기를 생성하고 있습니까? (0) | 2023.10.31 |
Visual Studio Server Explorer는 사용자 지정 데이터베이스 공급자를 지원합니까? (0) | 2023.10.31 |
AJAX, 하위 도메인 및 SSL (0) | 2023.10.31 |
객체 배열에서 속성이 검색과 일치하는 객체의 인덱스를 찾는 가장 빠른 방법 (0) | 2023.10.31 |