国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

nodejs和react實現即時通訊簡易聊天室功能

2024-05-06 16:54:22
字體:
來源:轉載
供稿:網友

npx create-react-app socketio-demo

進入socketio-demo目錄 運行eject進行拆包,本項目也可以不拆,這是個人習慣。 注意如果運行eject命令最好在項目初始階段執行,已經開始編寫后不要再使用容易出現bug,新人謹慎使用eject命令

yarn eject

項目拆包后創建服務器文件夾和文件

mkdir servertype null>index.js

創建完成后目錄如下

nodejs,react,即時通訊,聊天室

編寫即時通訊(聊天室)后臺

安裝nodejs插件

npm i express http socket.io nodemon

進入server文件夾下的index.js頁面開始編寫后臺程序

const app = require('express')(); const server = require('http').Server(app); const io = require('socket.io')(server); //設置端口9093 server.listen(9093); //創建socket.io連接 io.on('connection', function (socket) {  //獲取messages事件  socket.on('messages', function (data) {   //向所有連接進行廣播  socket.broadcast.emit('messages', data)   //對發出者進行廣播,用戶名加上我  data.user=data.user+'[我]'  socket.emit('messages', data)  }); });

編寫即時通訊(聊天室)前臺

后臺編寫完畢,可以在src目錄中編寫前臺內容 安裝需要用到的react-router和redux依賴

npm i redux react-redux react-router react-router-dom

在src中創建io文件夾 在io文件夾中創建所需要的文件

cd srcmkdir iocd iotype null>login.jstype null>socket-demo.jstype null>socket-demo.cssmkdir authcd authtype null>auth.js

創建完成后目錄如下

nodejs,react,即時通訊,聊天室

這里auth.js文件是用來判斷用戶是否輸入昵稱,如已輸入昵稱可以進入聊天室,如沒有輸入昵稱則跳回登錄界面要求輸入昵稱

本項目當中我們把昵稱存在redux里實現登錄界面和聊天室界面的共用,當然現這個項目比較小,如果想用localStorage存在本地也可以,不過考慮到后期的擴展性以及加深對redux的理解我還是選擇存在redux當中

src文件夾下創建redux.js文件

src文件夾下創建redux文件夾,在redux文件夾下創建user.redux.js文件

cd srctype null>redux.jsmkdir reduxcd reduxtype null>user.redux.js

新建目錄如下

nodejs,react,即時通訊,聊天室

在redux文件夾下的user.redux.js中創建存儲用戶昵稱的reducer

const SET_USERNAME='SET_USERNAME' //初始化倉庫 const initState={user:''} //根據動作改變倉庫  export function User(state = initState, action) {  switch (action.type) {   case SET_USERNAME:    return {...state,user:action.payload}   default:    return state  } } //寫入昵稱動作 export function setUserName(user) {  return {   type:SET_USERNAME,  payload:user  } }

在src/redux.js文件中創建倉庫 combineReducers用于多個reducer的合并,這個項目中也可以不加,單為了后期擴展加入使用

import { combineReducers, createStore } from 'redux' import {User} from './redux/user.redux' //window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 用于chrome redux的擴展項let reducer = combineReducers({ User }) let store = createStore(  reducer,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())  export default store

這樣就可以在頁面當中使用redux了

下一步在app.js中引入redux,并把路由搭建起來 在src/app.js中寫入

import React from 'react';import {HashRouter as Router,Route,Switch} from 'react-router-dom'import Login from "./io/login";import SocketDemo from "./io/socket-demo";import {Provider} from 'react-redux'import store from './redux'import Auth from "./io/auth/auth";function App() { return (  <Provider store={store}>   <Router>    <Auth></Auth>    <Switch>     <Route exact path='/' component={Login}/>     <Route exact path='/talk' component={SocketDemo}/>    </Switch>   </Router>  </Provider> );}export default App;

在寫頁面之前我們先安裝修飾符插件

npm i babel-plugin-transform-decorators-legacy

Babel >= 7.x 時安裝 @babel/plugin-proposal-decorators

npm i @babel/plugin-proposal-decorators

在package.json中babel項中配置,注意plugins放在presets前否則容易報錯

"babel": {  "plugins": [   ["@babel/plugin-proposal-decorators", { "legacy": true }]  ],  "presets": [   "react-app"  ] }

好了這樣就可以使用裝飾付了

下面我們來編寫判斷是否設置用戶名的程序 打開src/io/auth下的auth.js文件

import React from 'react'; import {connect} from 'react-redux' import {withRouter} from 'react-router-dom' //獲取reducer @connect(  state=>state,  {} ) //獲取router @withRouter class Auth extends React.Component{  componentDidMount() {   //如果有用戶名就跳到聊天頁,如沒有則跳到登陸頁。  if(this.props.User.user){    this.props.history.push('/talk')   }else {    this.props.history.push('/')   }  }  render() {   return null  } }  export default Auth

編寫輸入昵稱并跳轉步驟 打開src/io/login.js文件

import React from 'react';import './socket-demo.css';import {connect} from 'react-redux'import {setUserName} from '../redux/user.redux'@connect( null, {setUserName})class Login extends React.Component{ constructor(props) {  super(props);  this.state={   user:''  }  this.login=this.login.bind(this)  this.onKeyDown=this.onKeyDown.bind(this) } //鍵盤點擊跳轉  onKeyDown(e){  switch (e.keyCode) {   case 13:    this.login();    return;   default:    return;  } } //添加鍵盤事件  componentDidMount() {  document.addEventListener("keydown", this.onKeyDown) } //賦值state  handleChange(title,target){  this.setState({   [title]:target.target.value  }) } //賦值并跳轉到聊天室頁面  login(){  let {user}=this.state;  if(user!==null && user.trim()!==''){   this.props.setUserName(user);   this.props.history.push('/talk')  } } render() {  return (   <div className='loginDiv'>    <input type='text' placeholder='輸入昵稱' onChange={v=>this.handleChange('user',v)} />    <button onClick={this.login}>進入聊天室</button>   </div> ); }}export default Login

下面是重頭戲,聊天室的前端展示的核心代碼 打開src/iosocket-demo.js文件

import React from 'react'import io from 'socket.io-client'import {connect} from 'react-redux'import './socket-demo.css'const url='ws://localhost:9093'const socket = io(url);@connect( state=>state, {})class SocketDemo extends React.Component{ constructor(props) {  super(props);  this.state={   message:'',   user:this.props.User.user,   messages:[]  }  this.send=this.send.bind(this)  this.login=this.login.bind(this)  this.onKeyDown=this.onKeyDown.bind(this) } componentDidMount() {  //輸入歡迎信息   this.login()  //增加回車事件   document.addEventListener("keydown", this.onKeyDown)  //socket.io連接后臺   io(url).on('connect', ()=>{   console.log('connect');   socket.on('messages', data => {    //返回用戶列表     this.setState({     messages:[...this.state.messages,data]    })    if(this.refs.showDiv){     this.refs.showDiv.scrollTop=2000    }   });  }); } componentWillUnmount() {  //斷開socket io連接   io('ws://localhost:9093').on('disconnect', function(){   console.log('disconntect');  });  document.removeEventListener("keydown", this.onKeyDown) } //鼠標回車事件  onKeyDown(e){  switch (e.keyCode) {   case 13:    this.send();    return; default:    return;  } } //向后臺發送信息  send(){  let {user,message}=this.state;  console.log(this.refs.showDiv);  socket.emit('messages', {user,message});  this.setState({   message:''  }) } login(){  let user=this.props.User.user;  const obj={user:'作者',message:`歡迎${user}來到聊天室`}  if(user.trim()!==''){   this.setState({    user:user,    messages:[obj]   })  } } //賦值state  handleChange(title,target){  this.setState({   [title]:target.target.value  }) } render() {  let cn='showInfo'  return (   <div>    <div className='talkDiv'>     <div className='operatingDiv'>      <input type='text'          placeholder='請在此輸入聊天信息'          onChange={v=>this.handleChange('message',v)}          value={this.state.message}      />      <button onClick={this.send}>發送鏈接</button>     </div> <div ref='showDiv' className='showDiv'>     {      this.state.messages.map((v,index)=>{       if(index===0){        cn='titleInfo'       }else{        cn='showInfo'       }       return (        <div className={cn} key={index}>         <span>{v.user}:</span>         <span>{v.message}</span>        </div> )      })     }    </div>    </div>   </div> ); }}export default SocketDemo;

最后加上src/iosocket-demo.css

body{   background: #008DB7;  font-family: 'Microsoft YaHei UI';  } .loginDiv{   text-align: center;  margin: 150px auto 0;  width: 250px; } .loginDiv input[type='text']{   display: inline-block;  box-sizing: border-box;  border-radius: 5px;  padding-left: 5px;  border: none;  width: 250px;  height: 35px;  line-height: 35px; } .loginDiv button{   display: inline-block;  box-sizing: border-box;  border-radius: 5px;  padding-left: 5px;  border: none;  width: 250px;  height: 35px;  line-height: 35px;  margin-top: 10px;  background: #0067A2;  color: #ffffff; }  .talkDiv{   position: fixed;  top: 0;  left: 0;  right: 0;  bottom: 0; }  .talkDiv .operatingDiv{   position: fixed;  bottom: 0;  left: 0;  right: 0;  height: 40px;  display: flex; }  .talkDiv .operatingDiv input[type='text']{   flex: 1;  height: 40px;  line-height: 40px;  box-sizing: border-box;  padding-left: 10px; } .talkDiv .operatingDiv button{   display: inline-block;  box-sizing: border-box;  border-radius: 5px;  border: none;  width: 250px;  height: 40px;  line-height: 40px;  background: #0067A2;  color: #ffffff; }  .talkDiv .showDiv{   position: fixed;  bottom: 40px;  left: 0;  right: 0;  top: 0;  font-size: 16px;  color: #ffffff;  overflow: auto; } .talkDiv .showDiv .titleInfo{   padding: 10px;  color: yellow;  font-size: 20px; } .talkDiv .showDiv .showInfo{   padding: 10px; }

在package.json中加入命令行

"scripts": {  "start": "node scripts/start.js",  "build": "node scripts/build.js",  "server": "nodemon server/index.js"},
  • 運行后臺 yarn server
  • 運行前臺 yarn start

啟動程序

總結

以上所述是小編給大家介紹的nodejs和react實現即時通訊簡易聊天室功能,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 东阿县| 绥宁县| 明光市| 永康市| 石景山区| 维西| 新宁县| 兰州市| 静海县| 驻马店市| 云和县| 康定县| 多伦县| 稷山县| 镇雄县| 西华县| 会理县| 兴义市| 郯城县| 开鲁县| 额尔古纳市| 奉节县| 东阿县| 营山县| 延津县| 渑池县| 桃园市| 安图县| 延长县| 涟水县| 灵宝市| 万载县| 勐海县| 和田县| 新宁县| 扶绥县| 怀远县| 泰州市| 灵山县| 玛曲县| 荆州市|