【问题标题】:React with Socket IO: Broadcast is not working对 Socket IO 做出反应:广播不起作用
【发布时间】:2020-09-24 17:07:32
【问题描述】:

我正在使用 Socket IO 做游戏。每个房间都使用一个沟通渠道。当玩家下注时,我想发送给对手。但是,玩家也在接收消息

这是我的 React 组件

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>
    )
}

这是我的后台

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, () => {
})

当玩家下注时,它应该发出“下注”并且只有对手才能收到下注的价格。但这不是它的工作方式。 这是我点击一次按钮后两个玩家的控制台: 在我点击按钮的玩家控制台中,打印了两次!!!我不想打印,只在对方(即打印一次)

我是 Socket.io 的初学者,如果这是一个基本概念,请见谅。

【问题讨论】:

  • 如果点击按钮 3 次,控制台是否会记录 3 次输出?
  • 是的@Ayudh。我点击页面的控制台打印“对手10 \n对手10 \n对手10 \n对手10 \n对手10 \n对手10”并在对手“对手10 \n对手10 \n对手10”跨度>

标签: javascript reactjs sockets


【解决方案1】:

从您的 toBet 函数中删除 const socket = ...

【讨论】:

  • 输出是一样的吗?请查看更新的答案。对您的 toBet 函数执行相同的操作。只声明一次套接字
  • 我打开了两个浏览器。在第一个浏览器 A 中,我单击按钮,它会打印两次“对手”。在第二个浏览器 B 中,它被打印一次“oponnent”。如果我点击浏览器 B 的按钮,浏览器 B 打印一次“oponnent”,浏览器 A 打印两次“oponnent”。
  • 我认为问题出在start.on("start room")里面的start.on("opponent made bet")。但我不知道如何解决
猜你喜欢
  • 1970-01-01
  • 2017-12-29
  • 2021-08-15
  • 2020-11-21
  • 1970-01-01
  • 2019-05-31
  • 1970-01-01
  • 2017-08-28
相关资源
最近更新 更多