Hello everyone!
I'm having some problems using WebSocket WS in my application.
After many tests on my localhost, where everything works perfectly, I placed the application in a virtual machine in google cloud and the code simply stopped working, presenting the following error:
WebSocket connection to 'ws://localhost:8000/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
This is the code that has stopped working (in bold):
import Vue from 'vue'
import Vuex from 'vuex'
import shortid from 'shortid'
import { WebSocketBridge } from 'django-channels'
import { randomUsername } from '@/utils'
import router from '@/router'
Vue.use(Vuex)
const bus = new Vue()
const socket = new WebSocketBridge()
const state = {
lobby: {},
socket: socket,
socketConnected: false,
bus: bus,
emulator: {
state: 'chilling',
},
}
const getters = {
bus: state => () => state.bus,
store: state => () => state.store,
userIsHost: (state, getters) => match => {
return state.user.identifier === match.host.identifier
},
}
export const SHOW_CONTROLS_DEFAULT = false
export const LOBBY_LIST_REQUEST = 'lobby.list_request'
export const LOBBY_LIST_RESPONSE = 'lobby.list_response'
export const LOBBY_GET_BY_ID = 'lobby.get_by_id'
export const MATCH_CREATED = 'match.created'
export const MATCH_UPDATED = 'match.updated'
export const MATCH_DELETED = 'match.deleted'
export const MATCH_HOST = 'match.host'
export const MATCH_JOIN = 'match.join'
export const MATCH_LEAVE = 'match.leave'
export const MATCH_ADD_PLAYER = 'match.add_player'
export const MATCH_PAIRING_ANSWER = 'match.rtc_answer'
export const MATCH_PAIRING_OFFER = 'match.rtc_offer'
export const MATCH_PAIRING_CANDIDATE = 'match.rtc_candidate'
export const MATCH_KICK_PLAYER = 'match.kick_player'
export const MATCH_PAIR_CONTROLLER = 'match.pair_controller'
export const MATCH_CLOSE = 'match.close'
export const MATCH_STATS_START = 'match.stats_start'
export const MATCH_CONTROLS_SHOW = 'match.controls_show'
export const MATCH_CONTROLS_HIDE = 'match.controls_hide'
export const MATCH_FULLSCREEN = 'emulator.fullscreen'
export const CHAT_MESSAGE = 'chat.relay_message'
export const CHAT_FOCUS_ENTER = 'chat.focus_enter'
export const CHAT_FOCUS_EXIT = 'chat.focus_exit'
export const USER_DISCONNECT = 'user.disconnect'
export const USER_HEARTBEAT = 'user.heartbeat'
export const ROM_STORE = 'rom_store'
export const EMULATOR_STATE = 'emulator.state'
export const EMULATOR_PLAY = 'emulator.play'
const objectWithoutKey = (object, key) => {
const {[key]: deletedKey, ...otherKeys} = object
return otherKeys
}
const actions = {
[MATCH_HOST] ({commit, state}, match) {
const matchChannelName = Object.keys(match)
const matchWithoutRom = objectWithoutKey(match[matchChannelName], 'rom')
console.log(matchWithoutRom)
commit(MATCH_HOST, match)
commit(EMULATOR_STATE, {state: 'loading'})
state.socket.stream(MATCH_HOST).send(matchWithoutRom)
},
[MATCH_JOIN] ({commit, state}, match) {
const join = {
identifier: state.user.identifier,
match: match.channel_name,
username: state.user.username,
}
state.socket.stream(MATCH_JOIN).send(join)
},
[MATCH_ADD_PLAYER] ({commit, state}, match) {
console.log('MATCH_ADD_PLAYER')
console.log(match)
const join = {
identifier: shortid.generate(),
match: match.channel_name,
username: randomUsername(),
}
state.socket.stream(MATCH_ADD_PLAYER).send(join)
},
[MATCH_PAIR_CONTROLLER] ({commit, state}, payload) {
const match = payload.match
const userIdentifier = payload.userIdentifier
console.log('MATCH_PAIR_CONTROLLER')
console.log(match)
const join = {
identifier: userIdentifier,
match: match.channel_name,
username: 'egal',
}
state.socket.stream(MATCH_PAIR_CONTROLLER).send(join)
},
[MATCH_KICK_PLAYER] ({commit, state}, payload) {
state.socket.stream(MATCH_KICK_PLAYER).send(payload)
},
[MATCH_CLOSE] ({commit, state}, payload) {
state.socket.stream(MATCH_CLOSE).send(payload)
},
}
const mutations = {
[ROM_STORE] (state, payload) {
state.rom = payload.rom
},
[LOBBY_GET_BY_ID] (state, match) {
console.log(match)
},
[LOBBY_LIST_RESPONSE] (state, payload) {
state.lobby = payload
},
[MATCH_CREATED] (state, payload) {
state.lobby = {
...state.lobby,
...{[payload.channel_name]: payload},
}
},
[MATCH_UPDATED] (state, payload) {
state.lobby = {
...state.lobby,
[payload.channel_name]: payload,
}
},
[MATCH_DELETED] (state, payload) {
let {[payload.channel_name]: foo, ...newLobby} = state.lobby
state.lobby = newLobby
},
[MATCH_HOST] (state, payload) {
state.lobby = {
...state.lobby,
...payload,
}
const channelName = Object.keys(payload)[0]
router.push({
name: 'match',
params: {
channel_name: channelName,
host: true,
},
})
},
[MATCH_JOIN] (state, join) {
const kJoin = {
[join.identifier]: join,
}
const match = state.lobby[join.match]
Vue.set(match, 'player_count', match.player_count + 1)
match.takers = {
...match.takers,
...kJoin,
}
if (join.identifier === state.user.identifier) {
state.user = {
...state.user,
port: join.port,
}
}
router.push({
name: 'match',
params: {
channel_name: match.channel_name,
host: false,
},
})
},
[MATCH_ADD_PLAYER] (state, join) {
const kJoin = {
[join.identifier]: join,
}
const match = state.lobby[join.match]
Vue.set(match, 'player_count', match.player_count + 1)
match.takers = {
...match.takers,
...kJoin,
}
},
[MATCH_PAIR_CONTROLLER] (state, join) {
const kJoin = {
[join.identifier]: join,
}
const match = state.lobby[join.match]
match.takers = {
...match.takers,
...kJoin,
}
},
[MATCH_PAIRING_OFFER] (state, foo) {
// console.log(foo)
},
[MATCH_PAIRING_ANSWER] (state, foo) {
// console.log(foo)
},
[MATCH_PAIRING_CANDIDATE] (state, foo) {
// console.log(foo)
},
[MATCH_KICK_PLAYER] (state, payload) {
const match = state.lobby[payload.match]
Vue.set(match, 'player_count', match.player_count - 1)
const {[payload.taker]: foo, ...newTakers} = match.takers
match.takers = newTakers
},
[MATCH_LEAVE] (state, payload) {
const match = state.lobby[payload.match]
Vue.set(match, 'player_count', match.player_count - 1)
const {[payload.taker]: foo, ...newTakers} = match.takers
match.takers = newTakers
},
[CHAT_MESSAGE] (state, message) {
console.log('Got chat message:', message)
const match = state.lobby[message.match]
if (!match.hasOwnProperty('chat')) {
match['chat'] = []
}
match['chat'].push(message)
},
[USER_DISCONNECT] (state, payload) {
console.log('USER_DISCONNECT')
if (Object.keys(payload).length === 0 && payload.constructor === Object) {
return
}
const match = state.lobby[payload.match]
Vue.set(match, 'player_count', match.player_count - 1)
if (match.host.identifier === payload.user) {
let key = payload.match
let {[key]: dontMatter, ...newLobby} = state.lobby
state.lobby = newLobby
} else {
console.log('TAKER!')
const {[payload.user]: foo, ...newTakers} = match.takers
match.takers = newTakers
}
},
[EMULATOR_STATE] (state, payload) {
console.log('Setting new emulator state:', payload.state)
Vue.set(state.emulator, 'state', payload.state)
},
[MATCH_STATS_START] (state, payload) {
},
}
**function createWebSocketPlugin (socket, bus) {
return store => {
var url = 'ws://localhost:8000'
if (process.env.NODE_ENV === 'testing') {
url = process.env.SMES_BACKEND_URL.replace('http://', 'ws://')**
}
socket.connect(url)
socket.listen()
const channels = ['chat', 'lobby', 'match', 'user']
channels.forEach(function (channel) {
socket.demultiplex(channel, (message, stream) => {
const mutationType = stream + '.' + message.action
store.commit(mutationType, message.payload)
const payloadCopy = JSON.parse(JSON.stringify(message.payload))
bus.$emit(mutationType, payloadCopy)
})
})
socket.socket.addEventListener('open', function () {
console.log('Connected to websocket backend:', url)
store.state.socketConnected = true
socket.stream(LOBBY_LIST_REQUEST).send({})
})
socket.socket.addEventListener('close', function () {
console.log('Disconnected from backend:', url)
store.state.socketConnected = false
})
}
}
const plugin = createWebSocketPlugin(socket, bus)
export default new Vuex.Store({
modules: {},
state,
getters,
actions,
mutations,
plugins: [plugin],
})
Any help?
Thanks!
Hey
Not quite familiar with google cloud, but maybe i help you
How do you run websocket server?
Is docker used?
Hi, @stas-ut21
Yes.
My application is all loaded and executed in Docker.
Hi, @stas-ut21
Yes.
My application is all loaded and executed in Docker.
Do you publish a port from Docker to the local machine?
Yes.
It is posted to run on port 80 And if I change to port 443, nothing works at all.
The link on which the application is running is:
your client application is trying to connect to localhost
that is, in order for me to use it I need to deploy a copy of your websocket server
deploy websocket server to google cloud too
Look
I have opened a websocket server locally on port 8000
And opened your page: http://35.231.96.83/
Page normally connected to my server
But in order for people to be able to communicate with your backend, you still need to send the client part to your backend in the cloud
and I also see in your code that you will not connect anywhere except the local machine
var url = 'ws://localhost:8000'
and I also see in your code that you will not connect anywhere except the local machine
var url = 'ws://localhost:8000'
Exactly.
However, even if I change the path to my public IP, the error persists.
I've been researching here, apparently it has to do with the TLS protocol but I'm not sure ...
Look
I have opened a websocket server locally on port 8000
And opened your page: http://35.231.96.83/Page normally connected to my server
But in order for people to be able to communicate with your backend, you still need to send the client part to your backend in the cloud
How do I make this work, given that my backend is already on the server? Could you guide me?
Sorry to bother you, thank you very much for all your support and attention.
As suggested by @stas-ut21, you have to use the URL where your WebSocket server is running. For example if your WebSocket server is running on 35.231.96.83:8080 you have to use this URL.
const ws = new WebSocket('ws://35.231.96.83:8080');
If you are running an HTTPS server use wss:.
I'm going to close to this as answered. Discussion can continue if needed.
@stas-ut21 @lpinca
I have tried all the changes indicated, none of them are working. all have the same problem.
any suggestion?
thank you very much.
I have excatly the same problem. Under Linux it works perfectly. Under Windows 10 I get the conn refused error. So maybe it has to do with Win10. Firewall is disable. Have no idea how to fix it
@dj0abr
Hello
please write the error that you get in the console
And more: what url do you have on the client in the browser?
sorry, I posted in the wrong github project. I am running another c++ websocket.
Most helpful comment
Look
I have opened a websocket server locally on port 8000
And opened your page: http://35.231.96.83/
Page normally connected to my server
But in order for people to be able to communicate with your backend, you still need to send the client part to your backend in the cloud