在 React + NodeJS 上通过浏览器的 WebSockets
WebSockets via browser on React + NodeJS
我正在 NodeJS 上构建一个 websocket 聊天服务,运行。它已经在终端上运行,如果你想尝试,请检查终端客户端包。 https://www.npmjs.com/package/@redstone-solutions/hackerchat-client
它在终端上运行良好,现在我正在开发一个包来集成网络应用程序(javascript、react 等),但我无法通过浏览器连接到 websocket。
基本上,这是创建 websocket 的后端:
(我没有使用 socket.io,唯一的依赖是 uuid)
async initialize(eventEmitter: NodeJS.EventEmitter): Promise<http.Server> {
const server = http.createServer((request: http.IncomingMessage, response: http.ServerResponse) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Request-Method', '*');
response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
response.setHeader('Access-Control-Allow-Headers', '*');
response.writeHead(200, { 'Content-Type': 'text/plain' })
response.end('Hacker chat server is running!\n\nPlease connect with websocket protocol.')
})
server.on('upgrade', (request, socket) => {
socket.id = uuid()
const headers = [
'HTTP/1.1 101 Web Socket Protocol Handshake',
'Upgrade: WebSocket',
'Connection: Upgrade',
''
]
.map(line => line.concat('\r\n'))
.join('')
socket.write(headers)
eventEmitter.emit(EventTypes.event.NEW_USER_CONNECTED, socket)
})
return new Promise((resolve, reject) => {
server.on('error', reject)
server.listen(this.port, () => resolve(server))
})
}
这是我对新的 React 应用程序的尝试,我使用的方式与我在终端客户端上使用的方式相同。
function App() {
useEffect(() => {
async function run() {
const componentEmitter = new Events()
const connection = await createConnection()
console.log(connection)
}
run()
}, [])
async function createConnection() {
const options = {
port: '9898',
host: 'localhost',
headers: {
Connection: 'Upgrade',
Upgrade: 'websocket'
}
}
const request = http.request(options)
request.end()
return new Promise(resolve => {
request.once('upgrade', (response, socket) => resolve(socket))
})
}
return <div />
}
react 应用程序上的请求永远不会升级! console.log(连接)永远不会被调用。
我不确定我是否使用了与浏览器不兼容的资源(例如 http 包)...
应用非常simple/small,如果需要完整代码:
https://github.com/redstone-solutions/hackerchat-server
https://github.com/redstone-solutions/hackerchat-terminal-client
有什么想法吗?
我找到了连接套接字的方法,但我需要重构我的应用程序。
const server = new WebSocket('ws://localhost:9898')
使用 JavaScript 中的原生 WebSocket API,我可以建立连接。
有了http库,请求永远不会升级,我相信这个库不能完全在浏览器上工作。
我正在 NodeJS 上构建一个 websocket 聊天服务,运行。它已经在终端上运行,如果你想尝试,请检查终端客户端包。 https://www.npmjs.com/package/@redstone-solutions/hackerchat-client
它在终端上运行良好,现在我正在开发一个包来集成网络应用程序(javascript、react 等),但我无法通过浏览器连接到 websocket。
基本上,这是创建 websocket 的后端: (我没有使用 socket.io,唯一的依赖是 uuid)
async initialize(eventEmitter: NodeJS.EventEmitter): Promise<http.Server> {
const server = http.createServer((request: http.IncomingMessage, response: http.ServerResponse) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Request-Method', '*');
response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
response.setHeader('Access-Control-Allow-Headers', '*');
response.writeHead(200, { 'Content-Type': 'text/plain' })
response.end('Hacker chat server is running!\n\nPlease connect with websocket protocol.')
})
server.on('upgrade', (request, socket) => {
socket.id = uuid()
const headers = [
'HTTP/1.1 101 Web Socket Protocol Handshake',
'Upgrade: WebSocket',
'Connection: Upgrade',
''
]
.map(line => line.concat('\r\n'))
.join('')
socket.write(headers)
eventEmitter.emit(EventTypes.event.NEW_USER_CONNECTED, socket)
})
return new Promise((resolve, reject) => {
server.on('error', reject)
server.listen(this.port, () => resolve(server))
})
}
这是我对新的 React 应用程序的尝试,我使用的方式与我在终端客户端上使用的方式相同。
function App() {
useEffect(() => {
async function run() {
const componentEmitter = new Events()
const connection = await createConnection()
console.log(connection)
}
run()
}, [])
async function createConnection() {
const options = {
port: '9898',
host: 'localhost',
headers: {
Connection: 'Upgrade',
Upgrade: 'websocket'
}
}
const request = http.request(options)
request.end()
return new Promise(resolve => {
request.once('upgrade', (response, socket) => resolve(socket))
})
}
return <div />
}
react 应用程序上的请求永远不会升级! console.log(连接)永远不会被调用。
我不确定我是否使用了与浏览器不兼容的资源(例如 http 包)...
应用非常simple/small,如果需要完整代码:
https://github.com/redstone-solutions/hackerchat-server
https://github.com/redstone-solutions/hackerchat-terminal-client
有什么想法吗?
我找到了连接套接字的方法,但我需要重构我的应用程序。
const server = new WebSocket('ws://localhost:9898')
使用 JavaScript 中的原生 WebSocket API,我可以建立连接。
有了http库,请求永远不会升级,我相信这个库不能完全在浏览器上工作。