PHP框架+gatewayworker实现在线1对1聊天--聊天界面布局+创建websocket连接(5)
文章目录
- 聊天界面布局
- html代码
- 创建websocket连接
- 为什么要绑定?
聊天界面布局
在View/Index目录下创建index.html
html代码
<div id="chat"><div id="nbar"><div class="pull-left">与牛德胜正在聊天...</div><div class="pull-right" id="to_user_status"><span>离线</span></div></div><div id="chat_content"><div class="media"><div class="media-left"><img class="media-object avatar" src="/Uploads/avatar/4.jpg"></div><div class="media-body"><h4 class="media-heading">牛德胜</h4><p class="chat_msg_left">对对对 </p></div></div><div class="media_right"><div class="media-body"><h4 class="media-heading">黎明</h4><p class="chat_msg_right">顶顶顶顶 </p></div><div class="media-right"><img class="media-object avatar" src="/Uploads/avatar/1.jpg"></div></div><div class="media"><div class="media-left"><img class="media-object avatar" src="/Uploads/avatar/4.jpg"></div><div class="media-body"><h4 class="media-heading">牛德胜</h4><p class="chat_msg_left">订单 </p></div></div><div class="media_right"><div class="media-body"><h4 class="media-heading">黎明</h4><p class="chat_msg_right">对对对 </p></div><div class="media-right"><img class="media-object avatar" src="/Uploads/avatar/1.jpg"></div></div></div><div class="form-inline" style="position: relative;"><div class="form-group"><div class="input-group"><div class="input-group-addon" onclick="emoj()">表情</div><input type="text" class="form-control" id="msgcontent"><div class="input-group-addon" style="cursor: pointer;" onclick="choose_image()">图片</div><input type="file" name="file" id="file" accept="image/*" style="display: none" onchange="send_image()"></div></div><button type="button" class="btn btn-primary" onclick="send_msg()">发送</button></div>
</div>
页面布局实现效果如下。
布局是个简单的事儿,重点就是聊天内容展示,左边是对方,右边是自己。这两个每个单独用一个div包裹起来。有新的聊天信息追加的时候比较方便。直接在最后追加。
创建websocket连接
<script>
ws=new WebSocket("ws://127.0.0.1:8282");ws.onmessage=function (e){// json数据转换成js对象var data = eval("("+e.data+")");var type = data.type || '';console.log(data)switch(type){// Events.php中返回的init类型的消息,将client_id发给后台进行uid绑定case 'init':// 利用jquery发起ajax请求,将client_id发给后端进行uid绑定$.post('/chat.php/Chat/bind', {client_id: data.client_id}, function(data){}, 'json'); break; default :alert(e.data);}}</script>
下面这句在页面加载的时候就创建了websocket连接。
ws=new WebSocket(“ws://127.0.0.1:8282”);
ws.onmessage这个函数是有消息从服务端推送过来的时候就自动接收。
还记得GatewayWorker\Applications\YourApp\Events.php文件里的内容吗,里边的这段代码就是有连接的时候,服务器就会自动回复一条消息,我们将这条消息以json字符串的形式发给客户端。定义了消息的类型init,也就是第一次连接的时候,初始化。
根据服务端返回的消息,将字符串json转为真的json,然后解析里边的数据
// json数据转换成js对象var data = eval("("+e.data+")");var type = data.type || '';
之后根据返回的数据类型,进行相应的处理。第一次初始化,根据服务端返回的client_id,把当前客户的id和client_id发送给服务端,让服务端把用户id和client_id进行绑定。
switch(type){// Events.php中返回的init类型的消息,将client_id发给后台进行uid绑定case 'init':// 利用jquery发起ajax请求,将client_id发给后端进行uid绑定$.post('/chat.php/Chat/bind', {client_id: data.client_id}, function(data){}, 'json'); break; default :alert(e.data);}
接下来在Controller文件夹下创建ChatController.php,里边添加一个bind方法,来绑定id和client_id
别忘了引用Gateway,这就是之前添加GatewayClient的原因。有了这个客户端,就可以在PHP的框架里直接对Gatewayworker进行操作。
use GatewayClient\Gateway;
public function bind(){$client_id=I('post.client_id');// 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值(ip不能是0.0.0.0)Gateway::$registerAddress = '127.0.0.1:1238';// 假设用户已经登录,用户uid和群组id在session中$uid = $_SESSION['user_id'];
// client_id与uid绑定Gateway::bindUid($client_id, $uid);}
到此,就实现了客户端以服务端的连接,并将客户端用户id与client_id进行绑定。
为什么要绑定?
服务端给每个链家创建一个client_id,这个id是一串很长的字符串:7f0000010b5400000006。这种怎么区分谁给谁发送呢。将用户id与client_id绑定后,只要给用户id发送信息,服务端自动找到对应的client_id发送信息。一个用户id可以绑定多个client_id,但是一个client_id只能绑定一个用户id。适用场景如下:
你可以打开多个网页跟同一个人聊天,每打开一个页面,就会创建一个socket连接,就会有一个client_id。都是你一个人聊天,用户的id是同一个。
相关文章:

PHP框架+gatewayworker实现在线1对1聊天--聊天界面布局+创建websocket连接(5)
文章目录 聊天界面布局html代码 创建websocket连接为什么要绑定? 聊天界面布局 在View/Index目录下创建index.html html代码 <div id"chat"><div id"nbar"><div class"pull-left">与牛德胜正在聊天...</div…...

LinuxUbuntu打开VSCode白屏解决方案
解决方法是 以root权限打开VSCode sudo /usr/share/code/code --no-sandbox --unity-launch...

在 ESP 上运行 AWTK
AWTK 基于 esp 的移植。 测试硬件平台为 ESP32-S3-Touch-LCD-4.3,其它平台请根据实际平台自行调整。 安装下载工具 建议下载离线版本 ESP IDF v5.3.2 下载代码 git clone https://github.com/zlgopen/awtk-esp.git cd awtk-esp git clone https://github.com/zlg…...
硬件工程师面试题 21-30
把常见的硬件面试题进行总结,方便及时巩固复习。其中包括网络上的资源、大佬们的大厂面试题,其中可能会题目类似,加强印象即可。 更多硬件面试题:硬件工程师面试题 1-10硬件工程师面试题 11-20 21、单片机最小系统需要什么&#x…...

开源架构的容器化部署优化版
上三篇文章推荐: 开源架构的微服务架构实践优化版(New) 开源架构中的数据库选择优化版(New) 开源架构学习指南:文档与资源的智慧锦囊(New) 我管理的社区推荐:【青云交社区…...

Qt使用CMake编译项目时报错:#undefined reference to `vtable for MainView‘
博主将.h文件和.cpp文件放到了不同的文件目录下面,如下图所示: 于是构建项目的时候就报错了#undefined reference to vtable for MainView,这个是由于src/view目录下的CMake无法自动moc头文件导致的,需要手动moc include/view目录…...

python学习笔记—12—
1. 布尔类型 (1) 定义 (2) 比较运算符 (3) 代码演示 1. 手动定义 bool_1 True bool_2 False print(f"bool_1的内容是:{bool_1}, 类型是:{type(bool_1)}") print(f"bool_2的内容是:{bool_2}, 类型是:{type(bool…...

==和===的区别,被坑的一天
在 JavaScript 中, 和 都用于比较两个值,但它们有一个重要的区别: 1. (宽松相等运算符) 进行比较时,会 自动类型转换(也叫做强制类型转换),即如果比较的两个值的类型不同,JavaScr…...
基于 GPUTasker 的 GPU 使用情况钉钉推送机器人实现
引言 https://github.com/cnstark/gputasker 随着 AI 模型的广泛应用,GPU 成为团队中最重要的资源之一。然而,如何实时监控 GPU 的使用情况并及时通知团队是一个值得关注的问题。为了更好地管理显卡资源,本文基于 GPUTasker,实现了…...
Python自学 - 函数初步(内置函数、模块函数、自定义函数)
1 Python自学 - 函数初步(内置函数、模块函数、自定义函数) 1.1 内置函数 几乎所有的编程都会提供一些内置函数,以便完成一些最基本的任务,Python提供了丰富的内置函数,熟悉内置函数可以给工作带来极大便利。 Python官方的内置函数介绍网…...

【生活】冬天如何选口罩(医用口罩,N95, KN95还是KP95?带不带呼吸阀门?带不带活性炭?)
💡总结一下就是: 日常防护的话,医用口罩就可以啦。要是想长时间佩戴N95(KN95)口罩的话也可以. 在高风险环境(像医院、疫情防控期间),一定要选不带呼吸阀门的N95口罩KN95)…...

HTML5新特性|01 音频视频
音频 1、Audio (音频) HTML5提供了播放音频文件的标准 2、control(控制器) control 属性供添加播放、暂停和音量控件 3、标签: <audio> 定义声音 <source> 规定多媒体资源,可以是多个<!DOCTYPE html> <html lang"en"> <head><…...

迅为RK3568开发板编译Android12源码包-设置屏幕配置
在源码编译之前首先要确定自己想要使用的屏幕并修改源码,在编译镜像,烧写镜像。如下图所示: 第一步:确定要使用的屏幕种类,屏幕种类选择如下所示: iTOP-3568 开发板支持以下种类屏幕: 迅为 LV…...
力扣hot100——图论
200. 岛屿数量 class Solution { public:int numIslands(vector<vector<char>>& grid) {int ans 0;vector<int> dx { 0, 1, 0, -1 };vector<int> dy { 1, 0, -1, 0 };int n grid.size(), m grid[0].size();vector<vector<int>> …...

Docker- Unable to find image “hello-world“locally
Docker- Unable to find image “hello-world“locally 文章目录 Docker- Unable to find image “hello-world“locally问题描述一. 切换镜像1. 编辑镜像源2. 切换镜像内容 二、 检查设置1、 重启dockers2、 检查配置是否生效3. Docker镜像源检查4. Dokcer执行测试 三、自定义…...

spring-boot启动源码分析(二)之SpringApplicationRunListener
在上一篇《spring-boot启动源码分析(一)之SpringApplication实例构造》后,继续看了一个月的Spring boot启动源码,初步把流程看完了,接下来会不断输出总结,以巩固这段时间的学习。同时也希望能帮到同样感兴趣…...

ELK入门教程(超详细)
什么是ELK? ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称(后来出现的filebeat属于beats家族中的一员,可以用来替代logstash的数据收集功能,比较轻量级),也被称为Elastic Stack。 Filebeat Filebeat是用于转…...

人工智能知识分享第六天-机器学习_逻辑回归(Logistic Regression)
简介 在机器学习中,分类问题是一种常见的任务,目标是根据输入特征将数据点分配到不同的类别中。为了实现分类,我们需要训练一个分类器,该分类器能够根据输入数据的特征进行预测。 逻辑回归(Logistic Regression&…...

基于Springboot + vue实现的校园周边美食探索及分享平台
🥂(❁◡❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞 💖📕🎉🔥 支持我:点赞👍收藏⭐️留言📝欢迎留言讨论 🔥🔥&…...

初学STM32 --- 外部SRAM
目录 SRAM简介 SRAM特性: XM8A51216 功能框图 8080并口读时序编辑 8080并口写时序 SRAM 读写操作步骤 FSMC介绍 FSMC时序介绍 FSMC控制器对内核地址映射编辑 FSMC HAL库相关驱动 SRAM驱动步骤 SRAM简介 静态随机存取存储器(Static Random-Access Memory&am…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...