好客租房移动web项目(3)

1、WebSocket的Demo

1.1、App.js

// node中是通过net核心模块来开发websocket
// 市面上有很多基于net模块开发的第三方模块,开发websocket特别的简单。
const WebSocket = require('ws')

// 创建webSocket服务
const server = new WebSocket.Server({ port: 8080 })

// 启动websocket服务
// 只要浏览器端连接了websocket,connention事件就会触发
server.on('connection', client => {
  console.log('客户端连接上了')
  client.send('欢迎光临')

  // 每当客户端给我们发送消息的时候,message事件就会触发
  client.on('message', data => {
    let msg = ''
    switch (data) {
      case '你好':
        msg = '废话,当然好'
        break
      case '你是男的':
        msg = '不,我是小姐姐'
        break
      case '约吗':
        msg = '丑拒'
        break
      default:
        msg = '你说啥呀'
    }
    client.send(msg)
  })
})

1.2、index.html





  
  
  
  Document



  
  

  


2、好客租房移动web项目

2.1、components

 --- home

(1)chat

--Chat.css

.chat-container {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.chat-title {
  position: absolute;
  top: 0;
  width: 100%;
  height: 40px;
  line-height: 40px;
  background-color: #d4e0ee;
  text-align: center;
  font-size: 20px;
  z-index: 2;
}
.chat-list {
  box-sizing: border-box;
  height: 100%;
  width: 100%;
  padding-top: 40px;
  overflow-y: scroll;
}
.chat-list ul {
  margin: 0;
  padding: 0;
}
.chat-list li {
  position: relative;
  list-style: none;
  background-color: #f3f3f3;
  padding: 0 15px;
  margin-top: 2px;
  height: 70px;
  line-height: 70px;
  overflow: hidden;
}
.chat-list li img {
  width: 60px;
  height: 60px;
  margin-left: 5px;
  margin-top: 5px;
}
.chat-list li .name {
  position: absolute;
  left: 90px;
  top: -15px;
}
.chat-list li .info {
  position: absolute;
  left: 90px;
  top: 15px;
}
.chat-list li .time {
  position: absolute;
  right: 20px;
  top: -15px;
}
.chat-window {
  position: fixed;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: #f0f0f0;
  z-index: 99999;
}
.chat-list::-webkit-scrollbar {
  width: 3px;
}
.chat-list::-webkit-scrollbar-thumb {
  background-color: #cbdaea;
  -webkit-border-radius: 2em;
  -moz-border-radius: 2em;
  border-radius: 2em;
  min-height: 2rem;
  background-clip: padding-box;
  border-radius: 5px;
}
.chat-list::-webkit-scrollbar-track {
  background-color: #fff;
}
.chat-list::-webkit-scrollbar-track-piece {
  height: 30px;
}

--Chat.jsx

import React from 'react'
import './Chat.css'
import moment from 'moment'
import ChatWindow from './ChatWindow'
class Chat extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      list: [],
      isShow: false,
      chatInfo: {}
    }
  }

  async componentDidMount() {
    let res = await this.axios.post('chats/list')
    let { meta, data } = res
    if (meta.status === 200) {
      this.setState({
        list: data.list
      })
    }
  }

  toChat = item => {
    // console.log(item)
    this.setState({
      isShow: true,
      chatInfo: {
        from_user: item.from_user,
        to_user: item.to_user,
        avatar: item.avatar,
        username: item.username
      }
    })
  }

  closeWindow = () => {
    this.setState({
      isShow: false
    })
  }

  render() {
    return (
      
{this.state.isShow && ( )}
聊天
    {this.state.list.map(item => (
  • avarter {item.username} {item.chat_msg} {moment(item.ctime).format('YYYY-MM-DD HH:mm:ss')}
  • ))}
) } } export default Chat

--ChatWindow.css

.chat-window-title {
  height: 40px;
  line-height: 40px;
  font-size: 20px;
  padding-top: 3px;
  background-color: #d4e0ee;
  position: absolute;
  width: 100%;
  text-align: center;
  box-sizing: border-box;
}
.chat-window-content {
  position: absolute;
  top: 40px;
  bottom: 126px;
  width: 100%;
  overflow-y: auto;
}
.chat-window-content ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.chat-window-content ul li {
  min-height: 60px;
  clear: both;
}
.chat-window-content ul li img {
  width: 50px;
  height: 50px;
  padding-top: 5px;
  padding-left: 5px;
  vertical-align: top;
  float: left;
}
.chat-window-content ul li span {
  display: inline-block;
  font-size: 20px;
  background-color: #fff;
  padding: 5px 10px;
  margin: 10px 60px 0 10px;
  width: 65%;
  min-height: 50px;
  float: left;
  box-sizing: border-box;
  word-break: break-all;
  word-wrap: break-word;
}
.chat-window-content ul li.chat-info-right img {
  float: right;
  padding-right: 5px;
}
.chat-window-content ul li.chat-info-right span {
  float: right;
  margin: 10px 6px 0 60px;
  background-color: lightgreen;
}
.chat-window-input {
  width: 100%;
  position: absolute;
  bottom: 0;
  background-color: #21b97a;
  min-height: 60px;
  text-align: right;
  padding: 5px;
}
.chat-ret-btn {
  position: absolute;
  left: 0;
  top: 8px;
}
.ui.form textarea {
  margin-bottom: 5px;
}

--ChatWindow.jsx

import React from 'react'
import { Icon, Form, Button, TextArea } from 'semantic-ui-react'
import './ChatWindow.css'
import handle from './wsmain'
class ChatWindow extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      list: [],
      client: '',
      msgContent: '',
      fromAvatar: ''
    }
  }

  getChatList = async () => {
    // 发送ajax请求,获取聊天数据
    let res = await this.axios.post('chats/info', {
      from_user: this.props.chatInfo.from_user,
      to_user: this.props.chatInfo.to_user
    })
    let { meta, data } = res
    if (meta.status === 200) {
      this.setState({
        list: data.list
      })
    }
  }

  // 聊天窗口组件挂载的时候,获取聊天列表信息
  async componentDidMount() {
    // 获取当前用户的头像
    let res = await this.axios.post('my/info', {
      user_id: localStorage.getItem('uid')
    })
    let { meta, data } = res
    if (meta.status === 200) {
      // 通过websocket连接服务器,得到client对象
      let currentUser = localStorage.getItem('uid') - 0
      // 参数1: 连接聊天服务器的id
      // 参数2: 回调函数,服务器每次给发送的消息,都在data中
      // 返回值:client对象
      let client = handle(currentUser, data => {
        // 该回调函数用来处理服务器返回的消息(其实就是对方发送消息)
        // 其实就是接收对方返回的消息
        let newData = JSON.parse(data.content)
        let newList = [...this.state.list, newData]
        this.setState({
          list: newList
        })
      })
      this.setState({
        client: client,
        avatar: data.avatar
      })
    }
    this.getChatList()
  }

  // 给服务器发送数据
  sendMsg = () => {
    // 给服务器发送的数据包含:
    // from_user: 从谁发
    // to_user: 给谁发
    // this.state.msgContent: 发送的内容

    let pdata = {
      id: new Date().getTime(),
      from_user: this.props.chatInfo.from_user,
      to_user: this.props.chatInfo.to_user,
      chat_msg: this.state.msgContent,
      avatar: this.state.avatar
    }
    // 把消息发送出去
    this.state.client.emitEvent('msg_text_send', JSON.stringify(pdata))
    // 重新渲染聊天列表
    let newList = [...this.state.list, pdata]
    this.setState({
      list: newList,
      msgContent: ''
    })
  }

  handleChange = e => {
    this.setState({
      msgContent: e.target.value
    })
  }
  render() {
    let currentUser = localStorage.getItem('uid') - 0
    return (
      
{this.props.chatInfo.username}
    {this.state.list.map(item => ( // 通过currentUser与from_user去比较
  • {/* 这个头像显示是错误 */} {item.chat_msg}
  • ))}