前置条件

swoole 后台不能再windocs 下运行  ,php要开启swoole4扩展,放行服务端9502端口

1.新建后台php文件

<?php
//创建WebSocket Server对象,监听0.0.0.0:9502端口
$ws = new Swoole\WebSocket\Server('0.0.0.0', 9502);//监听WebSocket连接打开事件
$ws->on('Open', function ($ws, $request) {$ws->push($request->fd, "hello, welcome\n");
});//监听WebSocket消息事件$ws->on('Message', function ($ws, $frame) {foreach ($ws->connections as $fd) {//$frame->fd 当前客户端的唯一标识//$frame->data 客户端发送 的数据//$ws->connections 获取所有的客户端连接对象if ($frame->fd == $fd) {$class = 'bubble me';} else {$class = 'bubble you';}$result = ['error_code' => 0,'data' => ['data' => $frame->data,'class' => $class],'msg' => '发送成功'];//发送群聊中的所有人$ws->push($fd, json_encode($result,256));}
});//监听WebSocket连接关闭事件
$ws->on('Close', function ($ws, $fd) {echo "client-{$fd} is closed\n";
});$ws->start();

2.新建前台php文件


<!DOCTYPE html>
<html lang="en" ><head><meta charset="UTF-8"><title>在线聊天室</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/css/reset.min.css"><link rel="stylesheet" href="/css/style.css"><script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head><body><div class="wrapper"><div class="container"><div class="right"><div class="top"><span><span class="name">聊天室</span></span></div><div class="chat" data-chat="person2"><!--template 相当于微信小程序block标签,没有实际样式输出,用来循环--><template v-for="item in chatList"><div :class="item.data.class">{{ item.data.data }}</div></template></div><div class="write"><input type="text"  v-model="word" @keyup.enter="send()"   /><a href="javascript:;" class="write-link send" @click="send()" ></a></div></div></div></div><script  src="/js/index.js"></script>
</body></html>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>var wsServer = 'ws://47.100.168.166:9502';var websocket = new WebSocket(wsServer);websocket.onopen = function (evt) {console.log("Connected to WebSocket server.");};websocket.onclose = function (evt) {console.log("Disconnected");};var vm = new Vue({el: '.wrapper',data: {word:'',chatList:[]},methods:{send(){websocket.send(this.word)this.word = ''}}})websocket.onmessage = function ({data}) {let json = eval('(' + data + ')')console.log(json)console.log(typeof json)let msgArr = vm.chatListmsgArr.push(json)};websocket.onerror = function (evt, e) {console.log('Error occured: ' + evt.data);};</script>

3.新建css文件reset.min.css,放入css文件夹中

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}

4.新建css文件style.css,放入css文件夹中

*, *:before, *:after {box-sizing: border-box;
}:root {--white: #fff;--black: #000;--bg: #f8f8f8;--grey: #999;--dark: #1a1a1a;--light: #e6e6e6;--wrapper: 1000px;--blue: #00b0ff;
}body {background-color: var(--bg);-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-rendering: optimizeLegibility;font-family: 'Source Sans Pro', sans-serif;font-weight: 400;background-image: url("../img/image.jpg");background-size: cover;background-repeat: none;
}.wrapper {position: relative;left: 50%;width: var(--wrapper);height: 800px;-webkit-transform: translate(-50%, 0);transform: translate(-50%, 0);
}.container {position: relative;top: 50%;left: 50%;width: 80%;height: 75%;background-color: var(--white);-webkit-transform: translate(-50%, -50%);transform: translate(-50%, -50%);
}
.container .left {float: left;width: 37.6%;height: 100%;border: 1px solid var(--light);background-color: var(--white);
}
.container .left .top {position: relative;width: 100%;height: 96px;padding: 29px;
}
.container .left .top:after {position: absolute;bottom: 0;left: 50%;display: block;width: 80%;height: 1px;content: '';background-color: var(--light);-webkit-transform: translate(-50%, 0);transform: translate(-50%, 0);
}
.container .left input {float: left;width: 188px;height: 42px;padding: 0 15px;border: 1px solid var(--light);background-color: #eceff1;border-radius: 21px;font-family: 'Source Sans Pro', sans-serif;font-weight: 400;
}
.container .left input:focus {outline: none;
}
.container .left a.search {display: block;float: left;width: 42px;height: 42px;margin-left: 10px;border: 1px solid var(--light);background-color: var(--blue);background-image: url("../img//name-type.png");background-repeat: no-repeat;background-position: top 12px left 14px;border-radius: 50%;
}
.container .left .people {margin-left: -1px;border-right: 1px solid var(--light);border-left: 1px solid var(--light);width: calc(100% + 2px);
}
.container .left .people .person {position: relative;width: 100%;padding: 12px 10% 16px;cursor: pointer;background-color: var(--white);
}
.container .left .people .person:after {position: absolute;bottom: 0;left: 50%;display: block;width: 80%;height: 1px;content: '';background-color: var(--light);-webkit-transform: translate(-50%, 0);transform: translate(-50%, 0);
}
.container .left .people .person img {float: left;width: 40px;height: 40px;margin-right: 12px;border-radius: 50%;
}
.container .left .people .person .name {font-size: 14px;line-height: 22px;color: var(--dark);font-family: 'Source Sans Pro', sans-serif;font-weight: 600;
}
.container .left .people .person .time {font-size: 14px;position: absolute;top: 16px;right: 10%;padding: 0 0 5px 5px;color: var(--grey);background-color: var(--white);
}
.container .left .people .person .preview {font-size: 14px;display: inline-block;overflow: hidden !important;width: 70%;white-space: nowrap;text-overflow: ellipsis;color: var(--grey);
}
.container .left .people .person.active, .container .left .people .person:hover {margin-top: -1px;margin-left: -1px;padding-top: 13px;border: 0;background-color: var(--blue);width: calc(100% + 2px);padding-left: calc(10% + 1px);
}
.container .left .people .person.active span, .container .left .people .person:hover span {color: var(--white);background: transparent;
}
.container .left .people .person.active:after, .container .left .people .person:hover:after {display: none;
}
.container .right {position: relative;float: left;width: 62.4%;height: 100%;
}
.container .right .top {width: 100%;height: 47px;padding: 15px 29px;background-color: #eceff1;
}
.container .right .top span {font-size: 15px;color: var(--grey);
}
.container .right .top span .name {color: var(--dark);font-family: 'Source Sans Pro', sans-serif;font-weight: 600;
}
.container .right .chat {position: relative;display: none;overflow: hidden;padding: 5px 35px 92px;border-width: 1px 1px 1px 0;border-style: solid;border-color: var(--light);height: calc(100% - 48px);/*justify-content: flex-end;*/flex-direction: column;
}
.container .right .chat.active-chat {display: block;display: flex;
}
.container .right .chat.active-chat .bubble {transition-timing-function: cubic-bezier(0.4, -0.04, 1, 1);
}
.container .right .chat.active-chat .bubble:nth-of-type(1) {-webkit-animation-duration: 0.15s;animation-duration: 0.15s;
}
.container .right .chat.active-chat .bubble:nth-of-type(2) {-webkit-animation-duration: 0.3s;animation-duration: 0.3s;
}
.container .right .chat.active-chat .bubble:nth-of-type(3) {-webkit-animation-duration: 0.45s;animation-duration: 0.45s;
}
.container .right .chat.active-chat .bubble:nth-of-type(4) {-webkit-animation-duration: 0.6s;animation-duration: 0.6s;
}
.container .right .chat.active-chat .bubble:nth-of-type(5) {-webkit-animation-duration: 0.75s;animation-duration: 0.75s;
}
.container .right .chat.active-chat .bubble:nth-of-type(6) {-webkit-animation-duration: 0.9s;animation-duration: 0.9s;
}
.container .right .chat.active-chat .bubble:nth-of-type(7) {-webkit-animation-duration: 1.05s;animation-duration: 1.05s;
}
.container .right .chat.active-chat .bubble:nth-of-type(8) {-webkit-animation-duration: 1.2s;animation-duration: 1.2s;
}
.container .right .chat.active-chat .bubble:nth-of-type(9) {-webkit-animation-duration: 1.35s;animation-duration: 1.35s;
}
.container .right .chat.active-chat .bubble:nth-of-type(10) {-webkit-animation-duration: 1.5s;animation-duration: 1.5s;
}
.container .right .write {position: absolute;bottom: 29px;left: 30px;height: 42px;padding-left: 8px;border: 1px solid var(--light);background-color: #eceff1;width: calc(100% - 58px);border-radius: 5px;
}
.container .right .write input {font-size: 16px;float: left;width: 392px;height: 40px;padding: 0 10px;color: var(--dark);border: 0;outline: none;background-color: #eceff1;font-family: 'Source Sans Pro', sans-serif;font-weight: 400;
}
.container .right .write .write-link.attach:before {display: inline-block;float: left;width: 20px;height: 42px;content: '';background-image: url("../img/attachment.png");background-repeat: no-repeat;background-position: center;
}
.container .right .write .write-link.smiley:before {display: inline-block;float: left;width: 20px;height: 42px;content: '';background-image: url("../img/smiley.png");background-repeat: no-repeat;background-position: center;
}
.container .right .write .write-link.send:before {display: inline-block;float: left;width: 20px;height: 42px;margin-left: 11px;content: '';background-image: url("../img/send.png");background-repeat: no-repeat;background-position: center;
}
.container .right .bubble {font-size: 16px;position: relative;display: inline-block;clear: both;margin-bottom: 8px;padding: 13px 14px;vertical-align: top;border-radius: 5px;
}
.container .right .bubble:before {position: absolute;top: 19px;display: block;width: 8px;height: 6px;content: '\00a0';-webkit-transform: rotate(29deg) skew(-35deg);transform: rotate(29deg) skew(-35deg);
}
.container .right .bubble.you {float: left;color: var(--white);background-color: var(--blue);align-self: flex-start;-webkit-animation-name: slideFromLeft;animation-name: slideFromLeft;
}
.container .right .bubble.you:before {left: -3px;background-color: var(--blue);
}
.container .right .bubble.me {float: right;color: var(--dark);background-color: #eceff1;align-self: flex-end;-webkit-animation-name: slideFromRight;animation-name: slideFromRight;
}
.container .right .bubble.me:before {right: -3px;background-color: #eceff1;
}
.container .right .conversation-start {position: relative;width: 100%;margin-bottom: 27px;text-align: center;
}
.container .right .conversation-start span {font-size: 14px;display: inline-block;color: var(--grey);
}
.container .right .conversation-start span:before, .container .right .conversation-start span:after {position: absolute;top: 10px;display: inline-block;width: 30%;height: 1px;content: '';background-color: var(--light);
}
.container .right .conversation-start span:before {left: 0;
}
.container .right .conversation-start span:after {right: 0;
}@keyframes slideFromLeft {0% {margin-left: -200px;opacity: 0;}100% {margin-left: 0;opacity: 1;}
}
@-webkit-keyframes slideFromLeft {0% {margin-left: -200px;opacity: 0;}100% {margin-left: 0;opacity: 1;}
}
@keyframes slideFromRight {0% {margin-right: -200px;opacity: 0;}100% {margin-right: 0;opacity: 1;}
}
@-webkit-keyframes slideFromRight {0% {margin-right: -200px;opacity: 0;}100% {margin-right: 0;opacity: 1;}
}

4.新建js文件index.js,放入js文件夹中

document.querySelector('.chat[data-chat=person2]').classList.add('active-chat');
document.querySelector('.person[data-chat=person2]').classList.add('active');var friends = {list: document.querySelector('ul.people'),all: document.querySelectorAll('.left .person'),name: '' },chat = {container: document.querySelector('.container .right'),current: null,person: null,name: document.querySelector('.container .right .top .name') };friends.all.forEach(function (f) {f.addEventListener('mousedown', function () {f.classList.contains('active') || setAciveChat(f);});
});function setAciveChat(f) {friends.list.querySelector('.active').classList.remove('active');f.classList.add('active');chat.current = chat.container.querySelector('.active-chat');chat.person = f.getAttribute('data-chat');chat.current.classList.remove('active-chat');chat.container.querySelector('[data-chat="' + chat.person + '"]').classList.add('active-chat');friends.name = f.querySelector('.name').innerText;chat.name.innerHTML = friends.name;
}

WebSocket实现简单多人聊天相关推荐

  1. 基于Python Tkiner、thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信

    基于Python Tkiner.thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信 完整代码下载地址:基于Python Tkiner.thread与soc ...

  2. WebSocket实现简单的web聊天室

    WebSocket实现简单的web聊天室 1.需要Tomcat7.0所以服务器 2.需要JDK7.0 3.手工加入Tomcat7.0中lib目录下的一下三个包catalina.jar.tomcat-c ...

  3. python多人聊天室_python实现简单多人聊天室

    本文实例为大家分享了python实现多人聊天室的具体代码,供大家参考,具体内容如下 刚开始学习python,写了一个聊天室练练手. Server.py import socket,select,thr ...

  4. socket.io php 聊天室,WebSocket学习(一)——基于socket.io实现简单多人聊天室

    前言 什么是Websocket呢? 我们都知道在Http协议中,客户端与服务器端的通信是靠客户端发起请求,然后服务器端收到请求再进行回应,这个过程中,客户端是主动的,服务器端是被动的.Websocke ...

  5. NIO网络编程实战之简单多人聊天室

    NIO网络编程实战 利用NIO编程知识,实现多人聊天室. 1. NIO编程实现步骤 第一步:创建Selector 第二步:创建ServerSocketChannel,并绑定监听端口 第三步:将Chan ...

  6. python聊天室_python实现简单多人聊天室

    本文实例为大家分享了python实现多人聊天室的具体代码,供大家参考,具体内容如下 刚开始学习python,写了一个聊天室练练手. Server.py import socket,select,thr ...

  7. java单人多人聊天_java简单多人聊天

    服务器端代码: package chat; import java.io.DataInputStream; import java.io.DataOutputStream; import java.i ...

  8. Python简单多人聊天室

    # ------------------------------服务器端-----------------------------------------# auther: kele # 创建时间:2 ...

  9. SpringBoot——SpringBoot集成WebSocket实现简单的多人聊天室

    文章目录: 1.什么是WebSocket? 2.Java中的WebSocket API 2.1 WebSocket开发中的相关注解及API方法 2.2 前端技术对WebSocket的支持 3.多人聊天 ...

  10. (Agora声网)多人视频聊天应用的开发(三)多人聊天

    转载于:Android多人视频聊天应用的开发(三)多人聊天-玖哥的书房-51CTO博客 http://blog.51cto.com/dongfeng9ge/2104587 本系列文章结合声网官方在Gi ...

最新文章

  1. Python使用matplotlib可视化箱图、seaborn中的boxplot函数可视化分组箱图、在箱图中添加抖动数据点(Dot + Box Plot)
  2. oracle 的替代变量和
  3. Python学习教程(Python学习路线):Day08-面向对象编程基础
  4. docker自动部署
  5. linux使用ping命令ping本机,Linux下使用ping命令判断网络的好坏
  6. ann2snn的代码分析
  7. 【grafana】grafana 添加 MySQL 本地无法连接
  8. 【Java】Java 8 新特性-----Lambda 表达式
  9. 《Algorithms》—— Dijkstra 的双栈算术表达式求值算法
  10. 和付费网盘说再见,自己起个网盘不香吗?| Java 开源项目
  11. 数据结构中的头结点和头指针
  12. 灵云语音识别(ASR)实现实时识别
  13. 021.4 IO流——字节、字符桥梁(编码解码)
  14. 2020总结:临渊羡鱼不如退而结网
  15. 躬身入境DIY - 《传奇动物园》北京沙盘活动精彩回顾
  16. (云安全)拖库-洗库-撞库
  17. 如何用c语言对隐函数求导,隐函数求导的方法
  18. 【C++】C++调用Python
  19. 业务系统如何集成工作流系统?_K2 BPM集成能力讲解
  20. SD卡检测插入卡槽方案

热门文章

  1. 淘客联盟系统维护光盘2008新春大礼包
  2. Fiddler Everywhere抓包之视频下载
  3. js事件冒泡与事件捕获、阻止事件冒泡和浏览器默认行为
  4. Spring Cloud (五):路由网关(Zuul)
  5. 【目标提取】计算机视觉中如何利用颜色和形状提取目标?
  6. 【建议收藏】1000套HTML静态网页设计期末大作业 (HTML+CSS+JS)
  7. MER 音乐情感识别-论文笔记8
  8. 在哪里看服务器cpu占用率,top命令查看服务器cpu使用情况等
  9. 手脱aspack变形壳
  10. 橘子学设计模式之原型模式