前端js后端nginx+php+workerman实现websocket通信

workerman是纯PHP开发的开源PHP 应用容器,可以通过composer安装,目前因为要用到客户端与服务器实时通信,故使用了workerman中的websocket模块功能

服务器端:

1.建一个目录,创建start.php文件,文件名随意

2.composer安装workerman

composer require workerman/workerman

3.根据worker示例编写代码

简单的开发示例-workerman手册

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';// 创建一个Worker监听2345端口,使用websocket协议通讯
// 不要把websocket写成了tcp或者http
$http_worker = new Worker("websocket://0.0.0.0:6789");// 启动4个进程对外提供服务
$http_worker->count = 4;$http_worker->onConnect = function(TcpConnection $connection)
{echo "connected:\n";//var_dump($connection);echo "new connection from ip " . $connection->getRemoteIp() . "\n";
};// 接收到浏览器发送的数据时回复hello world给浏览器
$http_worker->onMessage = function(TcpConnection $connection, $data)
{echo "get message:\n";var_dump($data);//var_dump($request);// 向浏览器发送hello world// Connection::send(mixed $data [,$raw = false])// 第二个参数是raw,发送的数据只是第一个参数,不要搞错了// https://www.workerman.net/doc/workerman/tcp-connection/send.html$connection->send('hello world' . $data);
};$http_worker->onClose = function(TcpConnection $connection)
{echo "connection closed\n";
};// 运行worker
Worker::runAll();

4.配置nginx

workerman默认是可以直接监听端口的,但是因为开发环境、防火墙、安全、其他项目等因素,js直接连服务器ip+端口,连不上,所以采用了nginx代理转发,server模块中添加如下location

location /websocket {proxy_pass http://127.0.0.1:6789;#js前端ws = new WebSocket('wss://www.example.com/websocket');#workerman里面$http_worker = new Worker("websocket://0.0.0.0:6789");#这里就是代理转发到本地的6789端口proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade";proxy_set_header Host $host;
}

前端:

1.编写js代码

// 创建 WebSocket 对象并建立连接
var ws = null;try{ws = new WebSocket('wss://www.haoqi100.com/websocket');
}catch(e){console.log("new socket catch", e)
}
console.log("get websocket:", ws)
console.log("init event:")
// 打开连接时触发的事件
ws.onopen = function(event) {console.log('WebSocket 已连接');// onopen里面send会断开连接,应该是因为打乱了握手顺序setTimeout(()=>{ws.send('i am ok')// 发送心跳,不然时间长了会断开heartBeat()}, 1)
};// 接收到消息时触发的事件
ws.onmessage = function(event) {console.log('接收到服务器的消息:', event.data);
};// 发生错误时触发的事件
ws.onerror = function(error) {console.error('WebSocket 错误:', error);
};// 关闭连接时触发的事件
ws.onclose = function(event) {console.log('WebSocket 已关闭', event);ws = null
};function heartBeat(){var heartInterval = setInterval(()=>{if(ws){ws.send('ping')}else{clearInterval(heartInterval)console.log("heartBeat finish")}}, 10000)
}

注意事项:

1.前端js里面ws.onopen不要马上send,可能会打乱握手顺序

2.服务端的send有两个参数,第二个可选参数不会当成数据发送,不要搞错了

3.注意自己实现一个心跳,以免长时间没有收发数据导致连接断开

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/60799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人人必学的微信群变现打造课,让你的私域营销快人一步

标题&#xff1a;私域营销进阶之微信群变现课&#xff0c;助你快速实现营销目标 引言&#xff1a; 随着互联网的发展&#xff0c;私域营销成为了许多企业和个人推广和销售的重要方式。在私域营销中&#xff0c;微信群作为一个具有密集社交关系和高度互动性的平台&#xff0c;成…

【Golang】go条件编译

交叉编译只是为了能在一个平台上编译出其他平台可运行的程序&#xff0c;Go 作为一个跨平台的语言&#xff0c;它提供的类库势必也是跨平台的&#xff0c;比如说程序的系统调用相关的功能&#xff0c;能根据所处环境选择对应的源码进行编译。让编译器只对满足条件的代码进行编译…

ERROR: Failed building wheel for PyECLib

ERROR: Failed building wheel for PyECLib 具体原因 error: liberasurecode.so.1: cannot open shared object file: No such file or directory 解决方案 安装 liberasurecodehttps://opendev.org/openstack/liberasurecode Install dependencies Debian/Ubuntu hosts: …

uniapp的 picker 日期时间选择器

效果图&#xff1a; dateTimePicker.js function withData(param){return param < 10 ? 0 param : param; } function getLoopArray(start,end){var start start || 0;var end end || 1;var array [];for (var i start; i < end; i) {array.push(withData(i))…

说说构建流批一体准实时数仓

分析&回答 基于 Hive 的离线数仓往往是企业大数据生产系统中不可缺少的一环。Hive 数仓有很高的成熟度和稳定性&#xff0c;但由于它是离线的&#xff0c;延时很大。在一些对延时要求比较高的场景&#xff0c;需要另外搭建基于 Flink 的实时数仓&#xff0c;将链路延时降低…

jmeter传参base64卡顿如何解决

部分接口需要传图片base64格式参数&#xff0c;但是输入转为base64格式的图片参数&#xff0c;jmeter直接卡死&#xff0c;甚至电脑也卡死&#xff0c;此时&#xff0c;只需要去掉文件头描述&#xff1a;data:image/jpeg;base64, 即可

[Linux]进程

文章目录 1. 进程控制1.1 进程概述1.1.1 并行和并发1.1.2 PCB1.1.4 进程状态1.1.5 进程命令 1.2 进程创建1.2.1 函数1.2.2 fork() 剖析 1.3 父子进程1.3.1 进程执行位置1.3.2 循环创建子进程1.3.3 终端显示问题1.3.4 进程数数 1.4 execl和execlp函数1.4.1 execl()1.4.2 execlp(…

测试理论与方法----测试流程的第二个环节:测试计划

二、软件测试分类与测试计划 1、软件测试的分类(理解掌握) 根绝需求规格说明书&#xff0c;在设计阶段会产出的两个文档&#xff1a; 概要设计(HLD)&#xff1a;设计软件的结构&#xff0c;包含软件的组成&#xff0c;模块之间的层次关系&#xff0c;模块与模块之间的调用关系…

小程序密码显示与隐藏的实现

默认密码隐藏起来&#xff08;显示为点&#xff09;&#xff0c;后面的图标是闭眼&#xff1b;用户点击图标后&#xff0c;图标变成睁眼&#xff0c;同时把密码明文显示出来&#xff1b;如此循环 Page({data: {passwordType: true, // 切换是否密码框show_pass: false // 是否…

镜之Json Compare Diff

前言 “镜” 寓意是凡事都有两面性,Json 对比也不例外! 因公司业务功能当中有一个履历的功能,它有多个版本的 JSON 数据需要对比出每个版本的不同差异节点并且将差异放置在一个新的 JSON 当中原有结构不能变动,差异节点使用数组对象的形式存储,前端点击标红即可显示多个版本的节…

Ubuntu20.04如何更换国内源-阿里云源

1.备份源文件 cp /etc/apt/sources.list /etc/apt/sources.list.bak 2.打开源文件&#xff0c;注释默认的源 vim /etc/apt/sources.list ## 注释原本内容 # deb http://mirrors.ivolces.com/ubuntu/ focal main restricted universe multiverse # deb-src http://mirrors.ivolc…

pandas由入门到精通-数据清洗-分类数据

pandas-02-数据清洗&预处理 E. 分类数据1. 适用情况2. Categorical 扩展数据类型2.1 通过astype将一个Series转化为Categorical类2.2 通过pd.Categorical 生成Categorical类2.3 通过pd.Categorical.from_codes 将标签列表和整数列表转化为Categorical类2.4 Categorical类的…

Django(7)-项目实战-发布会管理

登录功能 模板页面 sign/templates/index.html <!DOCTYPE html> <html> <head><title>Login Page</title> </head> <body><h1>发布会管理</h1><form action"/login/" method"post"><la…

linux————ELK(日志收集系统集群)

目录 一、为什么要使用ELK 二、ELK作用 二、组件 一、elasticsearch 特点 二、logstash 工作过程 INPUT&#xff08;输入&#xff09; FILETER(过滤) OUTPUTS&#xff08;输出&#xff09; 三、kibana 三、架构类型 ELK ELKK ELFK ELFKK EFK 四、构建ELk集群…

Android基于JNI的Java与C++互调

java调用C++: #include <jni.h> //导出c函数格式 extern "C" JNIEXPORT //供JNI调用 JNICALL 函数名格式 Java_包名_类名_函数名(包名.替换为_) Java_com_example_getapplist_MainActivity_stringFromJNI 包名:com_example_getapplist 类名:MainActi…

异常的捕获和处理

目录 一、异常 1.异常概述 1.1认识异常 1.2Java异常体系结构 2.Java异常处理机制 2.1异常处理 2.2捕获异常 2.2.1使用try-catch捕获异常 2.2.2使用try-catch-finally处理异常 2.2.3使用多重catch处理异常 2.3抛出异常 2.3.1使用throws声明抛出异常 2.3.2使用throw…

管理类联考——逻辑——形式逻辑——汇总篇——知识点突破——形式逻辑——选言假言——要么、或者与箭头的关系

角度 或则转化/鲁滨逊定律 (1)或者变箭头: P ∨ Q = ┐ P → Q = ┐ Q → P P∨Q=┐P→Q=┐Q→P P∨

详细介绍typescript的所有变量类型

目录 1. 任意类型&#xff08;Any&#xff09;2. 数字类型&#xff08;Number&#xff09;3. 字符串类型&#xff08;String&#xff09;4. 布尔类型&#xff08;Boolean&#xff09;5. 数组类型&#xff08;Array&#xff09;6. 元组类型&#xff08;Tuple&#xff09;-需求明…

研磨设计模式day14模板方法模式

目录 场景 原有逻辑 有何问题 解决方案 解决思路 代码实现 重写示例 模板方法的优缺点 模板方法的本质 何时选用 场景 现在模拟一个场景&#xff0c;两个人要登录一个系统&#xff0c;一个是管理员一个是用户&#xff0c;这两个不同身份的登录是由后端对应的两个接…

Android笔记--Hilt

Hilt 是 Android 的依赖项注入库&#xff0c;可减少在项目中执行手动依赖项注入的样板代码。执行手动依赖项注入要求您手动构造每个类及其依赖项&#xff0c;并借助容器重复使用和管理依赖项。依赖注入的英文是Dependency Injection&#xff0c;简称DI,简单说一个类中使用的依赖…