我目前有一个非常简单的应用程序,它通过 websocket 连接向服务器发送和接收数据。本质上,该应用程序包含两个文本框,每次用户单击任一文本框以聚焦或单击离开时,都会向服务器发送通知,然后服务器将该消息广播到所有连接的实例。
这是我的代码如下:
App.js(客户端)
import React, { useState, useEffect } from 'react'
import io from 'socket.io-client'
import TextField from '@material-ui/core/TextField'
import './App.css'
import 'carbon-components/css/carbon-components.min.css';
import { TextArea } from 'carbon-components-react';
const socket = io.connect('http://localhost:4000')
function App() {
const [myUser, setMyUser] = useState(null)
const handleButtonClick = (e) => {
e.preventDefault();
setMyUser(e.target.value)
}
useEffect(() => {
socket.on("message", ({ user, id, focus }) => {
console.log(user, "clicked on", id, "with focus", focus)
})
}, [])
function setFocusTrue(id) {
const focus = true
console.log("emitting: ", myUser, id, focus)
socket.emit('message', { myUser, id, focus })
}
function setFocusFalse(id) {
const focus = false
console.log("emitting: ", myUser, id, focus)
socket.emit('message', { myUser, id, focus })
}
const Main = () => {
return (
<div>
<h1>Hello {myUser}</h1>
<TextArea
cols={50}
helperText="Optional helper text here; if message is more than one line text should wrap (~100 character count maximum)"
id="text1"
invalidText="Invalid error message."
labelText="Text area label"
placeholder="Placeholder text"
rows={4}
onFocus={() => setFocusTrue('text1')}
onBlur={() => setFocusFalse('text1')}
/>
<TextArea
cols={50}
helperText="Optional helper text here; if message is more than one line text should wrap (~100 character count maximum)"
id="text2"
invalidText="Invalid error message."
labelText="Text area label"
placeholder="Placeholder text"
rows={4}
onFocus={() => setFocusTrue('text2')}
onBlur={() => setFocusFalse('text2')}
/>
</div>
)
}
return (
<div>
{myUser === null ?
[
<div>
<button onClick={handleButtonClick} value="user1">User 1</button>
<button onClick={handleButtonClick} value="user2">User 2</button>
</div>
]
: <Main />
}
</div>
)
}
export default App
index.js(服务器)
const app = require('express')()
const http = require('http').createServer(app)
const io = require('socket.io')(http)
io.on('connection', socket => {
socket.on('message', ({ user, id, focus }) => {
console.log('received user', user, 'id', id, 'focus', focus)
io.emit('message', { user, id, focus })
})
})
http.listen(4000, function() {
console.log('listening on port 4000')
})
需要注意的一件事是,我正在用两个不同的用户(在两个隐身浏览器上运行)进行测试,因此每个用户都有条件呈现。对于此示例,当用户单击或远离文本框时,我可以看到文本框id
和focus
都是有效的,但由于某种原因,user
未定义。我可以看到实例按预期发出变量,但它们没有在服务器中正确接收。
在这种特殊情况下,用户 1 单击第一个文本框(从而将焦点呈现为真)。设置要发送到服务器的每个变量(如控制台日志所示)。服务器接收焦点和 id 变量,但出于奇怪的原因,用户未定义,即使它存在。最后,广播消息被发送到两个实例,但如前所述,id
并且focus
存在,但user
未定义。请参阅下面的屏幕截图。
客户端
服务器端控制台