亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 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教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美午夜久久久| 国产日本欧美在线观看| 久久久久久久久中文字幕| 亚洲欧美日韩视频一区| 精品国产老师黑色丝袜高跟鞋| 中文字幕久久久| 久久久精品电影| 精品国内产的精品视频在线观看| 91av在线看| 555www成人网| 欧美激情一区二区三区久久久| 91麻豆国产语对白在线观看| 日韩精品久久久久久福利| 久久免费高清视频| 国产精品丝袜白浆摸在线| 午夜免费日韩视频| 91精品久久久久久久久久入口| 亚洲人免费视频| 久久久999国产精品| 日韩人体视频一二区| 美女久久久久久久久久久| 国产亚洲精品久久久久久777| 成人欧美在线视频| 亚洲国产精品久久久久秋霞蜜臀| 国产区亚洲区欧美区| 92国产精品久久久久首页| 精品国内自产拍在线观看| 韩国欧美亚洲国产| 色琪琪综合男人的天堂aⅴ视频| 亚洲国产美女久久久久| 成人疯狂猛交xxx| 亚洲人成伊人成综合网久久久| 亚洲视频网站在线观看| 国产精品扒开腿做爽爽爽视频| 日韩一区二区三区在线播放| 亚洲另类图片色| 欧美麻豆久久久久久中文| 亚洲网站在线看| 日韩av在线导航| 国产精品一区二区电影| 亚洲欧美另类人妖| 日韩中文字幕不卡视频| 97精品在线视频| 国产精品久久久久久久午夜| www.国产一区| 久久精品免费播放| 97在线视频一区| 超碰97人人做人人爱少妇| www.亚洲一区| 欧美一二三视频| 中文字幕少妇一区二区三区| 亚洲第一区第二区| 久久久综合免费视频| 欧美激情性做爰免费视频| 92版电视剧仙鹤神针在线观看| 国产美女精品视频免费观看| 亚洲成人av中文字幕| 97在线日本国产| 亚洲国产成人在线视频| 欧美日韩亚洲成人| 亚洲a∨日韩av高清在线观看| 2018国产精品视频| 亚洲欧美日韩精品| 日韩av在线精品| 中文国产亚洲喷潮| 国产成人一区二区三区电影| 在线视频精品一| 成人午夜在线观看| 538国产精品一区二区在线| 亚洲jizzjizz日本少妇| 九九久久久久99精品| 欧美在线视频播放| 久久精品国产精品| 亚洲成人国产精品| 国产精品免费小视频| 岛国视频午夜一区免费在线观看| 亚洲3p在线观看| 国产成人精品免高潮费视频| 久久久91精品| 亚洲欧美成人一区二区在线电影| 综合136福利视频在线| 日韩成人av一区| 日韩免费在线播放| 国产精品久久久久久久久久ktv| 91国在线精品国内播放| 欧美午夜久久久| 国产+成+人+亚洲欧洲| 亚洲一二在线观看| 美女扒开尿口让男人操亚洲视频网站| 日韩激情视频在线播放| 69久久夜色精品国产7777| 欧美精品电影在线| 国产手机视频精品| 久久久久久久999精品视频| 97热在线精品视频在线观看| 欧美色欧美亚洲高清在线视频| 91精品国产高清自在线| 国产在线观看一区二区三区| 欧美黄色片视频| 欧美床上激情在线观看| 亚洲成人av在线播放| 91老司机精品视频| 成人黄色影片在线| 久久精品国产一区二区三区| 国产ts人妖一区二区三区| 成人福利视频在线观看| 国产91精品久久久| 成人精品久久av网站| 国产精品久久久亚洲| 日韩精品欧美国产精品忘忧草| 国产视频一区在线| 中文字幕亚洲第一| 精品人伦一区二区三区蜜桃免费| 91亚洲国产成人久久精品网站| 久久精品国产精品亚洲| 亚洲精品v天堂中文字幕| 亚洲天堂第一页| 欧美另类交人妖| 国语自产精品视频在线看一大j8| 欧美一级成年大片在线观看| 国产精品午夜一区二区欲梦| 一个人看的www欧美| 日韩在线资源网| 日韩av在线免费看| 久久久亚洲福利精品午夜| 亚洲成av人片在线观看香蕉| 欧美俄罗斯乱妇| 中文字幕国产精品久久| 久久久国产精品亚洲一区| 久久99青青精品免费观看| 亚洲在线视频观看| 91欧美激情另类亚洲| 国产精品一区=区| 欧美性xxxxx| 国产91精品高潮白浆喷水| 亚洲国产天堂久久综合网| 欧美午夜激情在线| 亚洲第一色在线| 91美女福利视频高清| 亚洲开心激情网| 亚洲欧美中文字幕| 亚洲福利视频网| 97香蕉超级碰碰久久免费的优势| 亚洲色图美腿丝袜| 日韩av在线免费观看一区| 中文字幕亚洲二区| 日韩久久精品电影| 国产一区二区色| 色综合久久精品亚洲国产| 亚洲一区二区三区乱码aⅴ蜜桃女| 久久亚洲精品一区| 久久久久久久久久av| 国产成人福利网站| 96pao国产成视频永久免费| 97人人爽人人喊人人模波多| 欧美成aaa人片免费看| 欧美电影免费观看| 91在线高清免费观看| 日韩视频在线一区| 亚洲999一在线观看www| 欧美人交a欧美精品| 中文综合在线观看| 欧美日韩国产999| 亚洲女人天堂av|