如何使用 Socket.io 和 MERN 堆栈进行一对一(私人)聊天

时间:2021-03-17 05:59:42

标签: reactjs socket.io chat p2p mern

目前它正在向用户列表中的每个用户发送和接收消息。你可以在图片中看到。

如何向特定用户发送消息,除了该用户之外,其他人都不应收到该消息?只有选定的用户才能进行一对一(私下)通信。 'showmessagespace' 函数有问题吗?另外,对于新用户,我想用他/她以前的消息或空白而不是普通的来打开他/她的新消息空间。

服务器代码:- 在服务器代码中,当我取消注释 'io.to(data.username).emit' 时,它不会将消息发送给接收者,只会在发送者选项卡上显示。

io.on('connection', (socket) => { /* socket object may be used to send specific messages to the new connected client */
  console.log('connection established',socket.id);
  socket.on('send', (data)=>{
    console.log("Receive data from single username",data)
    console.log('connection established',socket.id);
    console.log(data.username)
    socket.join(data.username)
  });
  socket.on('sended',data=>{
      console.log("gtf")
      // io.to(data.username).emit('sended',data)
      io.emit('sended',data)
  })
  
  socket.on('disconnect',()=>{
    console.log("disconnect")
  })
});

React(客户端)代码:当我点击用户的消息按钮时,showmessagespace 被调用,但是列表中的每个用户都会收到消息,每当我向特定用户发送消息时,它都会发送给每个连接的用户.当我发送消息时,您可以在此处看到它也在接收和发送。

enter image description here

但是当我更改用户时,它仍然向 sahil 和 abc 发送 msg:

enter image description here

import React, { Component } from 'react';
import { Link,Redirect } from 'react-router-dom';
import UserService from "../services/userservice";
import {getUsersFriend} from "../services/messageservice";
import io from "socket.io-client";
const SOCKET_IO_URL = "http://localhost:4000";

export default class Messages extends Component {
    constructor(props){
        super(props)
        this.socket = io(SOCKET_IO_URL)
        this.state = {
            currentUser: UserService.getCurrentUser(),
            isLoading:false,
            userdetails:[],
            show:false,
            username:'',
            message:'',
            senderusername:'',
            socketConnected:false,
            messages:[]
        };
        this.onTextboxChangeMessage = this.onTextboxChangeMessage.bind(this)
    }

    componentDidMount(){
        const {currentUser}=this.state
        this.fetchUser()
        this.socket.on('connect',()=> {
            this.setState({ socketConnected : true})
            this.socket.on('sended',(data)=>{ 
                console.log('component did mount',data)
                console.log(this.state.username==data.sendername)
                    console.log(this.state.username,data.username,data.senderusername)
                    this.setState({messages:[...this.state.messages,data]})
                    console.log(this.state.messages)                
            })
        })
        
    }

    async fetchUser(){
        try{
            const {currentUser} = this.state
            console.log(currentUser)
            const data = { userid : currentUser.user._id }
            console.log(data)
            let user = await getUsersFriend(data)
            this.setState({ userdetails: user });
            // console.log(user)
        }catch(err){
            console.log(err)
        }
    }

    showMessageSpace(elementusername){
        this.setState({
            show: true,
            username:elementusername
        });
        console.log(this.socket.id)
    }

    onTextboxChangeMessage(e){
        this.setState({ message:e.target.value})
    }

    SendMessage(username,message,senderusername){
        const {messages} =this.state
        if(this.state.socketConnected){
            console.log('if condition test',username,message,senderusername )
            // this.socket.emit('send',{username,message,senderusername,to:this.socket.id });
            this.socket.emit('send',{username });
            console.log('condition username',`${username}`,  )
            console.log(this.socket.id)
            this.socket.emit('sended',{username,message,senderusername });
        }
        this.setState( { message:'' })
    }

    

    render(){
        const { currentUser ,isLoading,userdetails,message,messages} = this.state;
        console.log(messages)
        if (isLoading) {
            return (<div><p>Loading...</p></div>);
        }

        if(!currentUser){
            return(
                <div>
                    <Redirect  to='/login' />
                </div>
            )
        }
        else{
        return(
            <div>
                <h1>Messages</h1>
                <div>
                    <p>Users</p>
                    {' '}
                    <ul className="collection">
                        {userdetails.map((element) => {
                            return(
                                <div key={element._id}>
                                    <li><Link to={`/dashboard/profile/:${element._id}`}>{element.username}</Link>{' '}<input 
                                    type="button" 
                                    id={element._id}
                                    value="Message"
                                    onClick={this.showMessageSpace.bind(this,element.username)} ></input></li>
                                </div>
                            );
                        })
                        }
                    </ul>
                    {' '}
                </div>
                {' '}
                    <Link to="/dashboard">Dashboard</Link>
                {' '}
                <div>
                {
                    this.state.show &&
                    (<div>
                        <h2>Send Message to : {' '}{this.state.username}</h2>
                        {' '}
                        <div className="jumbotron">
                            <h3>Body</h3>
                            <div>
                                <ul>
                                {messages.length > 0 && messages.map((msg,key) =>{
                                    return(<li key={key}>{msg.senderusername}<span>{' '}{msg.message}</span></li>);
                                })
                                }
                                </ul>
                            </div>
                        </div>
                        {' '}
                        <div>
                            {' '}
                            <input 
                            type="text"
                            name="message"
                            value={message}
                            onChange={this.onTextboxChangeMessage}
                            ></input>
                            <button className='btn btn-info' onClick={this.SendMessage.bind(this,this.state.username,this.state.message,currentUser.user.username )}>Send</button>
                        </div>
                        {' '}
                    </div>)
                    }
                </div>
            </div>
        )
        }
    }
}

0 个答案:

没有答案
相关问题