socket.io+egg+react_聊天室

技术栈:Socket+egg+react

前端react(vue和小程序都可以)
后端:egg,
通信工具:socket.io

socket官网:https://www.w3cschool.cn/socket/socket-1olq2egc.html
  • socket.io.js是什么呢:比如你和你的男朋友结婚了,你希望你们的家人都能见证你的幸福,这个聊天室就能帮你通知到你的家人们。
  • socket.io的工作流程:客户端 =》服务端 =》客户端

首先进入登录页,输入用户名进入聊天室,如果用户不存在,那么添加到数据库,然后进入聊天室,如果用户存在,那么提示用户已存在,然后重新输入用户名。

  • react: src/view/ChatRoom/index.js
import React, { Component , Fragment} from 'react';
import io from 'socket.io-client';
import './style.css';
import Axios from '[email protected]@axios';
class ChatRoom extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            userNameIpt:'',//login 的用户名
            userSay:'',//聊天室里的input
            hide:true,//隐藏聊天室
            socket:io('http://192.168.31.3:3333'),//配置socket
            userName:'',//进入聊天室之后保存的用户名
            wordList:[]//聊天记录
         }
    }
    render() { 
        let {userNameIpt,userSay,hide,wordList,userName} = this.state;
        return ( 
            <div className="chatRoom">
                <input type='text' 
                       value={userNameIpt} 
                       onChange={this.changeIpt.bind(this)} 
                       name="userNameIpt"
                       onKeyDown={this.setUser.bind(this)}
                       placeholder="输入用户名,按下回车"
                       />
                
                <div className={hide?'chatMask hide':'chatMask'}>
                    <header>聊天室</header>
                    <ul>
                        {
                            wordList && wordList.map((item,index)=>{
                                return (
                                    <li key={index}>
                                        <b>{item.userName}</b>
                                        <span>{item.userSay}</span>
                                    </li>
                                )
                            })
                        }
                    </ul>
                    <footer>
                        <input type="text" value={userSay} onChange={this.changeIpt.bind(this)} name="userSay"/>
                        <button onClick={this.sendUserSay.bind(this)}>发送</button>
                    </footer>
                </div>
            </div>
         );
    }
    changeIpt(e){
        this.setState({ [e.target.name]:e.target.value  });
    }
    setUser(e){
        let {userNameIpt,userName} = this.state;
        if(e.keyCode===13){
            //发送注册请求
            Axios
                .post('/login',{
                    userNameIpt
                })
                .then(res=>{

                    if(res.data.code===0){
                        //用户存在
                        
                    }else{
                        //用户不存在,成功注册
                        console.log(res.data)

                        this.setState({ userName:res.data.flag.userName , hide:false });
                        //注册成功保存用户名 然后 做显示聊天室
                    }
                    alert(res.data.msg)
                })


            // this.setState({ hide:false  });
        }
    }
    sendUserSay(){
        let {socket,userSay,userName} = this.state;
        socket.emit('message',{
            userSay,
            userName
        })
        this.setState({ userSay:''  });
    }
    componentDidMount(){
        let {socket,wordList} = this.state;
        socket.on('showMsg',(data)=>{
            console.log(data)
            wordList.push(data)
            this.setState({ wordList  });
        })
    }
}
export default ChatRoom;

  • socket: socket/app.js
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);

io.on('connection', function(socket){
  console.log('一个用户连接了');
  socket.on('message',function (data) { 
      let {userSay,userName} = data;
      socket.emit('showMsg',{userSay,userName})//对用户自己的
      socket.broadcast.emit('showMsg',{userSay,userName})//广播的
   })
});

http.listen(3333, function(){
  console.log('listening on *:3333');
});
  • egg: egg/app/router.js
'use strict';
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.post('/login', controller.login.index)
};

  • egg:egg/app/controller/login.js
'use strict';
const Controller = require('egg').Controller;
class LoginController extends Controller {
  async index() {
    const { ctx } = this;
    let userNameIpt = ctx.request.body.userNameIpt;
    let result = await ctx.service.login.set(userNameIpt);
    ctx.body = result;
  }
}
module.exports = LoginController;
  • egg: egg/app/service/login.js
module.exports = app => {
    const uid = require('uid')
  class LoginService extends app.Service {
        async set(userNameIpt) {
            
            let flag = await this.app.mysql.get('userList',{
                userName:userNameIpt
            })
            if(flag){
                return {
                    code:0,
                    msg:'用户存在'
                }
            }else{
                let result = await this.app.mysql.insert('userList',{
                    userName:userNameIpt,
                    id:uid(10)
                })
               let flag = await this.app.mysql.get('userList',{
                    userName:userNameIpt
                })
                return {
                    code:1,
                    msg:'注册成功',
                    flag
                }
            }
        }
  }
  return LoginService
}

中途遇到的几个问题:
服务端渲染 需要在index.html里引入 script 标签 socket.io.js
在Vue or React 里,客户端需要执行 cnpm install socket.io --save
引入后,配置时候需要注意 io(’‘http://localhost:3333") 需要别人访问的时候改成具体的 io(’'http://192.168.2.11:3333") ;

发布了103 篇原创文章 · 获赞 19 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/M106588L/article/details/101076470