vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度。因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那么容易了。功能虽然不多,但还是有收获。设计和实现思路较为拙劣,恳请各位道友指正

可以达到的需求

  • 能查看在线用户列表
  • 能发送和接受消息

使用到的框架和库

  • socket.io做为实时通讯基础
  • vuex/vue:客户端Ui层使用
  • Element-ui:客户端Ui组件

类文件关系图

服务端:

客户端:

服务端实现

实现聊天服务器的相关功能,包含通讯管道的创建、用户加入、消息的接受与转发等。

一、通讯服务建立

build/server-config.js:聊天服务器的入口

let socketIo = require('socket.io');
let express = require('express');
let cxt = require('../src/services-server'); let httpPort = 9001;
let channelId = 1
let app = express(); app.get('/',function(req,res){
res.send('启动成功:' + httpPort);
}); let server = require('http').createServer(app);
let io = socketIo(server);
io.on('connection',function(socket){
console.log('有客户端连接');
cxt.createChannel(channelId++,socket)
});
server.listen(httpPort); //用server连接
console.log('io listen success !! ' + httpPort);
  • 通过express创建一个server对象,然后利用socketIo创建io对象
  • 然后通过io的on方法监听connection事件
  • 当有客户端连接时,触发connection事件,县立即调用"服务端上下文(后面简称cxt)"的createChannel方法创建一个管道,此时的管道上是没有用户信息的。

二、创建上下文(服务端上下文)

实现一个聊天室上下文,包含:用户、房间、消息、管道等数组,所以代码都在service-server目录中。

  • index.js:聊天室服务端上下文创建入口,创建context,并初始化房间到上下文中。
  • context.js:聊天室服务端上下文类,用户、房间、消息、管道等类在此中做集中管理。
  • room目录:包含房间和房间集合的实现
  • channel:服务端与客户端通讯的管道类
    结合"通讯服务建立"中的connectiong事件的触,其后转到cxt.createChannel方法
createChannel (id, socket) {
let channel = new Channel(id, socket, this)
channel.init()
channel.index = this.channels.length
this.channels.push(channel)
}

此时会创建一个管道实例,然后初始化管道实例,并将管道添加到管道数组中。以下是初始化管道实例的代码:

init () {
let self = this
let roomInfo = this.cxt.room.collections[0]
this.roomInfo = roomInfo
this.socket.join('roomId' + roomInfo.id)
this.socket.emit(this.cxt.eventKeys.emit.sendRooms, roomInfo) /* send出去一个默认的房间 */
this.socket.on(this.cxt.eventKeys.client.registerUser, function (id, name) {
console.log(id + '-' + name + '--' + self.id)
self.cxt.createUserById(id, name, self.id)
}) /** 新用户注册 */
this.socket.on(this.cxt.eventKeys.client.newMsg, function (msg) { /** 发送消息 */
self.notifyMsg(msg)
console.log(msg)
self.cxt.addMsg(msg)
})
this.socket.on(this.cxt.eventKeys.client.closeConn, function () {
console.log(self.id + '--关闭连接')
self.cxt.remove(self)
})
this.sendUsers()
}

在初始化管道实例时做了如下事件:

  • 将通讯socket添加一个到房间中,方便后期好广播消息
  • 向当前连接上来的socket发送房间信息,设定为第一个房间
  • 监听三个事件:用户注册、新消息、关闭连接。此处都要逻辑处理,可以参考源码。

客户端实现

主要实现连接服务、注册用户、发送和接受消息的功能。首先以main.js为入口,且需要先装配好vue相关配件,如vuex、ElemUi、客户端通讯管道等,然后创建vue实例和连接消息服务器,代码如下:

import '../node_modules/bootstrap/dist/css/bootstrap.css'
import Vue from 'vue'
import ElemUi from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
import App from './App'
import * as stores from './store'
import { Keys } from './uitls'
import { getCxt } from './services-client' let initRoomInfo = Keys.SETROOMINFO
Vue.use(ElemUi)
/* eslint-disable no-new */
new Vue({
store: stores.default,
el: '#app',
template: '<App/>',
components: { App },
created: function () {
let self = this
getCxt().createIo(this, function (roomInfo) {
stores.busCxt.init() /** 初始化view与service层的交互层(业务层) */
self.$store.dispatch(initRoomInfo, roomInfo)
getCxt().refUsers(function (users) {
stores.busCxt.userCxt.refUsers(users)
})
})
}
})

一、与服务端的通讯

service-client目录中实例的与消息服务器通讯,其中包含创建用户、接受和发送消息等。一个客户端只能拥有一个消息管道,以下代码是消息管理的创建:

import * as io from 'socket.io-client'
import Context from './context' let eventKeys = require('../services-uitls/event.keys')
let url = 'http://localhost:9001/'
let cxt = null export function getCxt () {
if (cxt == null) {
cxt = new Context(url, eventKeys, io)
}
return cxt
}

在main.js中的vue实例的created勾子中调用了Context的createIo实例方法,用于创建一个与消息服务器的连接,并接受其中房间发送回来的房间信息。然后就初始化业务层。

二、vuex的结合

在store目录中实现,包含了vuex类相关的实现,还有业务层的实现。其中业务层会引用"客户端通讯管道",而vuex实现类有可能会引用业务层相关实现类,以此实现ui到"消息服务器"的通讯。 store/index.js代码如下:

import Vuex from 'vuex'
import Vue from 'vue' import RoomViewCxt from './room/roomViewCxt'
import UserViexCxt from './userViewCxt'
import MsgViewCxt from './msg/msgViewCxt'
import BusCxt from './indexForBus' let _busCxt = new BusCxt() let _rvCxt = new RoomViewCxt()
let _uvCxt = new UserViexCxt(_busCxt.userCxt)
let _mvCxt = new MsgViewCxt() let opt = {
state: null,
getters: null,
mutations: null,
actions: null
}
_rvCxt.use(opt)
_uvCxt.use(opt)
_mvCxt.use(opt) Vue.use(Vuex) let store = new Vuex.Store(opt)
export default store
export const busCxt = _busCxt /** 业务处理上下文 */
export function getBusCxt () {
return _busCxt
}

三、组件

组件只实现了 用户注册、主界面容器、消息发送和消息接受等。组件只会引用store目录中相关类,不会直接引用管道类。

  • Login.vue:用户注册组件
  • HChat.vue:主界面容器组件
  • Message/MsgWriter.vue:发送消息组件
  • Message/MsgList.vue:接受和显示消息列表组件

如何运行实例

  • 源码地址[2019-09-11更新,由于原下载地址失效]
  • cnpm run install 安装所有的依赖
  • npm run sokcetIo 启动消息服务器
  • npm run dev 启动客户端
  • 示例截图

vue + socket.io实现一个简易聊天室的更多相关文章

  1. 原生NodeJs制作一个简易聊天室

    准备工作 安装NodeJs环境 安装编译器Sublime 如果网速不理想,可以百度一下如何加快npm的速度~ 使用node搭建一个简单的网站后台 做完准备工作之后,新建文件夹chatroom,在cha ...

  2. 利用socket.io+nodejs打造简单聊天室

    代码地址如下:http://www.demodashi.com/demo/11579.html 界面展示: 首先展示demo的结果界面,只是简单消息的发送和接收,包括发送文字和发送图片. ws说明: ...

  3. 基于Node.js+socket.IO创建的Web聊天室

    这段时间进了一个新的项目组,项目是用Appcan来做一个跨平台的移动运维系统,其中前台和后台之间本来是打算用WebSocket来实现的,但写好了示例后发现android不支持WebSocket,大为受 ...

  4. 真刀实战地搭建React+Webpack+Express搭建一个简易聊天室

    一.前面bb两句 因为自惭(自残)webpack配置还不够熟悉,想折腾着做一个小实例熟悉.想着七夕快到了,做一个聊天室自己和自己聊天吧哈哈.好了,可以停止bb了,说一下干货. 二. 这个项目能学到啥? ...

  5. 利用socket.io实现多人聊天室(基于Nodejs)

    socket.io简单介绍 在Html5中存在着这种一个新特性.引入了websocket,关于websocket的内部实现原理能够看这篇文章.这篇文章讲述了websocket无到有,依据协议,分析数据 ...

  6. Socket入门笔记 用TcpClient实现一个简易聊天室

    效果 实现思路 使用TcpListener建一个服务器,接收所有客户端发送的消息,然后由服务器再发送到其他客户端 客户端使用TcpClient,发消息给服务器,接收服务器的消息,不和其他客户端直接交互 ...

  7. node+websocket创建简易聊天室

    关于websocket的介绍太多,在这就不一一介绍了,本文主要实现通过websocket创建一个简易聊天室,就是90年代那种聊天室 服务端 1.安装ws模块,uuid模块,ws是websocket模块 ...

  8. node.js+websocket实现简易聊天室

    (文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) websocket提供了一种全双工客户端服务器的异步通信方法,这种通信方法使用ws或者wss协议,可 ...

  9. php_D3_“简易聊天室 ”实现的关键技术 详解

                      PHP+MySQL实现Internet上一个简易聊天室的关键技术  系统目标: 聊天室使用数据库汇集每个人的发言,并可将数据库内的发言信息显示在页面,让每个用户都可 ...

随机推荐

  1. mybatis 参数为list时,校验list是否为空, mybatis ${}与#{}的区别,Mybatis sql in

    1.mybatis 参数为list时,校验list是否为空 2. mybatis ${}与#{}的区别 简单来说#{} 解析的是占位符?可以防止SQL注入, 比如打印出来的语句 select * fr ...

  2. logback的日志配置文件

    日志配置文件logback.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE con ...

  3. python 自动化之路 day 14

    今日内容 http://www.cnblogs.com/wupeiqi/articles/5699254.html 群共享 s15Html课件 1. paramiko模块 https://github ...

  4. jq hide show

    var $ = function (id) { return document.getElementById(id); } //返回dom元素的当前某css值 var getCss = functio ...

  5. PHP函数 mysql_real_escape_string 与 addslashes 的区别

    addslashes 和 mysql_real_escape_string 都是为了使数据安全的插入到数据库中而进行的过滤,那么这两个函数到底是有什么区别呢? 首先,我们还是从PHP手册入手: 手册上 ...

  6. thinkPHP 模板中的语法

    一.导入CSS和JS文件   1.css link       js  scr        <link rel='stylesheet' type='text/css' href='__PUB ...

  7. CSS BUG 总结

    1.IE7 容器使用了滚动条  其子元素中使用 position:relative ,position变成了fixed,从而不随容器的滚动条滚动; 解决: 在其容器元素的属性中也加入 position ...

  8. Bootstrap3网上api文档地址

    http://v3.bootcss.com/css/#forms http://www.ziqiangxuetang.com/bootstrap/bootstrap-forms.html 另附加fa字 ...

  9. HTML5画布(CANVAS)速查简表

    HTML5画布(CANVAS)速查简表 http://www.webhek.com/misc/html5-canvas-cheat-sheet/

  10. jQuery如何实现点击页面获得当前点击元素

    获得jquery对象: function foo(e){ var obj = $(e.target); }