Javascript 使用套接字IO作出反应:广播不工作
我正在用Socket IO做一个游戏。每个房间都使用一个通信通道。当玩家下注时,我想把它发送到OPONENT。然而,玩家也收到了信息 这是我的反应组件Javascript 使用套接字IO作出反应:广播不工作,javascript,reactjs,sockets,Javascript,Reactjs,Sockets,我正在用Socket IO做一个游戏。每个房间都使用一个通信通道。当玩家下注时,我想把它发送到OPONENT。然而,玩家也收到了信息 这是我的反应组件 import React, {useState, useEffect} from "react" import { useParams, Redirect } from 'react-router-dom' import socketIOClient from "socket.io-client"; import { BACKEND_URL }
import React, {useState, useEffect} from "react"
import { useParams, Redirect } from 'react-router-dom'
import socketIOClient from "socket.io-client";
import { BACKEND_URL } from '../../constants'
export default function Room() {
const { id } = useParams();
const [room, setRoom] = useState({});
const [game,setGame] = useState({
state: 'waiting',
payload: {},
})
const [price, setPrice] = useState(10);
/**
* This function verify if the room exist
* If exists, set a variable with its properties
* If doesn't exist, return to the initial page
*/
useEffect(() => {
fetch(`${BACKEND_URL}/rooms`)
.then((response) => response.json())
.then(rooms => {
let auxRoom = undefined;
rooms.map((room) => {
if(room.id == id) {
auxRoom = room;
}
})
setRoom(auxRoom)
})
}, []);
/**
* This function set the begin of the game
* Define that the player is waiting
* And wait the signal to begin the game
*/
useEffect(() => {
const socket = socketIOClient(BACKEND_URL);
socket.emit("waiting room", id);
socket.on("start room", () => {
setGame({
state: 'playing',
payload: {}
})
socket.on('opponent made bet', (price) => {
console.log("opponent")
console.log(price)
})
})
}, [])
function toBet(event) {
const socket = socketIOClient(BACKEND_URL);
event.preventDefault();
//Emiting that the player made a bet
socket.emit("make a bet", id, price);
}
return(
<div>
{ !room ? //If the room doesn't exist, should be redirect
<Redirect to="/"/>
: null }
Estamos na sala {id}!
{
game.state == 'playing' ?
<div className="game">
<div className="scoreboard">
</div>
<div className="arena">
<label>Escolha o preço do petróleo:</label>
<select value={price} onChange={(event) => setPrice(event.target.value)}>
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
</select>
<button onClick={toBet}>Apostar</button>
</div>
</div>
: null
}
</div>
)
}
import React,{useState,useffect}来自“React”
从“react router dom”导入{useParams,Redirect}
从“socket.io客户端”导入socketIOClient;
从“../../constants”导入{BACKEND_URL}
导出默认功能室(){
const{id}=useParams();
const[room,setRoom]=useState({});
const[game,setGame]=useState({
声明:‘等待’,
有效载荷:{},
})
const[price,setPrice]=使用状态(10);
/**
*此功能用于验证房间是否存在
*如果存在,请使用其属性设置变量
*如果不存在,请返回初始页面
*/
useffect(()=>{
获取(`${BACKEND\u URL}/rooms`)
.then((response)=>response.json())
.然后(房间=>{
设auxRoom=未定义;
房间。地图((房间)=>{
如果(room.id==id){
auxRoom=房间;
}
})
休息室(辅助休息室)
})
}, []);
/**
*此功能设置游戏的开始
*定义玩家正在等待
*然后等待开始游戏的信号
*/
useffect(()=>{
const socket=socketIOClient(后端URL);
插座发射(“候诊室”,id);
插座.on(“启动室”,()=>{
赛特加梅({
声明:“玩”,
有效载荷:{}
})
socket.on('对手下注',(价格)=>{
控制台日志(“对手”)
控制台日志(价格)
})
})
}, [])
功能待办事项(事件){
const socket=socketIOClient(后端URL);
event.preventDefault();
//发出这样的声音:玩家下了赌注
socket.emit(“下注”、id、价格);
}
返回(
{!文件室?//如果文件室不存在,则应重定向
:null}
埃斯塔莫斯·纳萨拉{id}!
{
game.state==“正在玩”?
埃斯科拉·奥普雷西奥·多佩特罗里奥:
setPrice(event.target.value)}>
10
20
30
叛徒
:null
}
)
}
这是我的后端
const app = require("express")();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
let rooms = [
{
id: 1,
name: 'Room 1',
owner: 'Bruna',
amountOfPlayers: 0,
},
{
id: 2,
name: 'Room 2',
owner: 'Amancio',
amountOfPlayers: 0,
}
]
function indexRoom(id) {
for(let i = 0; i < rooms.length; i++)
if(rooms[i].id == id)
return i;
}
app.get('/rooms', (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.json(rooms)
})
io.on('connection', (socket) => {
/**
* Socket that is responsible for start the game
* When two players connect, the game begins
*/
socket.on('waiting room', id => {
//A player get in the room
socket.join(id);
let index = indexRoom(id);
if(index != undefined) {
rooms[index].amountOfPlayers++;
//When are two players, should start the game
if(rooms[index].amountOfPlayers >= 2) {
io.to(id).emit('start room');
}
}
})
socket.on('make a bet', (id, price) => {
socket.broadcast.to(id).emit('opponent made bet', price)
})
})
http.listen(8080, () => {
})
const-app=require(“express”)();
const http=require('http')。createServer(应用程序);
const io=require('socket.io')(http);
出租房间=[
{
id:1,
姓名:“1号房间”,
所有者:“布鲁纳”,
层数:0,
},
{
id:2,
姓名:“2号房间”,
所有者:“Amancio”,
层数:0,
}
]
功能索引房间(id){
for(设i=0;i{
res.setHeader(“访问控制允许原点”,“*”);
res.json(房间)
})
io.on('连接',(套接字)=>{
/**
*负责启动游戏的套接字
*当两个玩家连接时,游戏开始
*/
socket.on('等候室',id=>{
//一名球员进入房间
socket.join(id);
let index=索引室(id);
如果(索引!=未定义){
房间[索引].amountOfPlayers++;
//当有两名球员时,应该开始比赛
if(房间[索引].AMONTOFPLAYERS>=2){
io.to(id.emit)(“启动室”);
}
}
})
socket.on('makeabout',(id,price)=>{
socket.broadcast.to(id.emit)(“对手下注”,价格)
})
})
http.listen(8080,()=>{
})
当一个玩家下注时,它应该发出“下注”,并且只有对手收到下注的价格。但事实并非如此。
这是两个玩家的控制台,在我点击按钮一次后:在玩家的控制台中,我点击按钮,它被打印两次!!!我不想打印,只在对手(即打印一次)
我是Socket.io的初学者,如果这是一个基本概念,我很抱歉。从您的
toBet
函数中删除const Socket=…
如果您单击按钮3次,控制台是否会记录三次输出?是@Ayudh。我单击的控制台页面上打印了“对手10\n对手10\n对手10\n对手10\n对手10\n对手10”和“对手10\n对手10\n对手10”中的输出是否相同?请看一下最新的答案。对toBet函数也执行同样的操作。只有在打开两个浏览器时才声明套接字。在第一个浏览器A中,我单击按钮,它会被打印两次“对手”。在第二个浏览器B中,它被打印一次“oponnet”。如果我点击浏览器B的按钮,浏览器B会打印一次“oponnent”,浏览器A会打印两次“oponnent”。我认为问题出在start.on(“对手下注”)内的start.on(“开始室”)。但我不知道如何修复