본문으로 건너뛰기

reconnect

웹소켓 연결이 끊겨진 상황을 세가지로 생각해보자
close가 된상황, 서버 자체가 restart된 상황, error 가 된 상황

nodejs websocket reconnect 키워드 검색으로 몇가지를 찾아봤다

링크 : NodeJS Websocket how to reconnect when server restarts

링크 : WebSocket: How to automatically reconnect after it dies

링크 : websocket : 끊겼을때 재시작 하기 (node.js / twelvedata)

이분 코드를 잘 참고해보자

function twelveDataConnect(){
const webSocket = new WebSocket(`wss://ws.twelvedata.com/v1/quotes/price?apikey=${config.key}`)

webSocket.onopen = async () => {
console.log('connection good')
const body = JSON.stringify({
action: 'subscribe',
params: {
symbols: Symbols
}
})
webSocket.send(body)

webSocket.onmessage = async (e) => {
// console.log('message', e)
// console.log('data', e.data)
const data = JSON.parse(e.data)
...

const interval = setInterval(() => {
const heartbeat = JSON.stringify({
action: 'heartbeat'
})
webSocket.send(heartbeat)
}, 10000)
}

webSocket.onclose = async (e) => {
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e);
setTimeout(function() {
twelveDataConnect();
}, 1000);
}
}

twelveDataConnect()

웹소켓 연결부터 연결된 후의 모든 동작을 twelveDataConnect() 라는 하나의 함수 내에 넣어두고 해당 함수를 실행합니다. 웹소켓이 onclose되는 시점에 setTimeout을 걸어서 종료 1초 후에 다시 웹소켓을 연결하도록 해두면 상용 서버에서 혹시나 웹소켓 연결이 끊기더라도 다시 재연결할 수 있습니다.

close가 되었을때 이벤트로 1초후에 재접속을 하게된다
그런데 서버 자체가 꺼졌다가 몇시간 후 다시 재부팅 되는 상황을 염두한다면 이 코드로 해결하기는 어려울 것 같다.


첫번째 링크의 이 코드가 괜찮아 보인다

const ws = require('ws')
let openedSocketFlag = null
const timeInterval = 5000
const port = 3000
const url = `ws://localhost:${port}`

function connect() {
const client = new ws(url)
return new Promise((resolve, reject) => {
console.log('client try to connect...')

client.on('open', () => {
console.log('WEBSOCKET_OPEN: client connected to server at port %s', port)
openedSocketFlag = true
resolve(openedSocketFlag)
})

client.on('message', (data) => {
console.log(data.toString())
})

client.on('close', (err) => {
console.log('WEBSOCKET_CLOSE: connection closed %o', err)
openedSocketFlag = false
reject(err)
})

client.on('error', (err) => {
console.log('WEBSOCKET_ERROR: Error', new Error(err.message))
openedSocketFlag = false
reject(err)
})
})
}

async function reconnect() {
try {
await connect()
} catch (err) {
console.log('WEBSOCKET_RECONNECT: Error', new Error(err).message)
}
}

reconnect()

// repeat every 5 seconds
setInterval(() => {
if (!openedSocketFlag) {
reconnect()
}
}, timeInterval)

reconnect()가 connect()를 호출하고 connect내부에서 소켓연결 플래그를 true / false 처리한다
인터벌 함수에서는 소켓연결 플래그만 확인하고 reconnect()함수를 호출할지 결정한다.