2022年9月2日10:05:03
gitee地址 https://gitee.com/zxadmin/luckysheet-phpserver 此项目目前定义为对接失败,当然Luckysheet也可以去除掉加密的部分,直接json通信就没问题 luckysheet 是前端测试代码 luckysheet/pako/examples/browser.html pako是加密测试代码 Luckysheet的 share多人协作数据发送对接流程: Luckysheet的配置 $(function () { // According to the browser language var lang = luckysheetDemoUtil.language() === 'zh' ? 'zh' : 'en'; //var isShare = luckysheetDemoUtil.getRequest().share; // '?share=1' opens the collaborative editing mode //var gridKey = luckysheetDemoUtil.getRequest().gridKey; // workbook id for collaborative editing, or directly define here var isShare = 1; // '?share=1' opens the collaborative editing mode var gridKey = "1079500#-8803#7c45f52b7d01486d88bc53cb17dcd2xc"; // workbook id for collaborative editing, or directly define here var options = null; if (isShare || gridKey) { // http://localhost:3000/?gridKey=12eyy789-kk45ofid-23737245 if (!gridKey) { alert('If gridKey is not provided in the address bar, please add it in the source code') } options = { container: "luckysheet", lang: lang, allowUpdate: true, updateImageUrl: "http://192.168.154.131" + "/luckysheet/updateImg", updateUrl: "ws://192.168.154.131:8888", gridKey: gridKey, loadUrl: "http://192.168.154.131" + "/luckysheet/load", loadSheetUrl: "http://192.168.154.131" + "/luckysheet/loadsheet" } } else { console.log(1111111); } luckysheet.create(options); }) 1,选请求 luckysheet/load接口 接口返回 [{"color":"","list_id":"1079500#-8803#7c45f52b7d01486d88bc53cb17dcd2xc","column":60,"index":"1","jfgird_select_save":[{"top_move":180,"top":180,"left":222,"column_focus":3,"width":73,"column":[3,3],"left_move":222,"width_move":73,"row":[9,9],"row_focus":9,"height_move":19,"height":19}],"rh_height":1790,"visibledatacolumn":[],"scrollTop":0,"block_id":"fblock","rowsplit":[],"visibledatarow":[],"jfgrid_selection_range":{},"name":"Sheet1","celldata":[],"ch_width":4748,"row":84,"scrollLeft":0,"id":350081777752215552,"chart":[],"config":{},"order":0,"status":1},{"color":"","list_id":"1079500#-8803#7c45f52b7d01486d88bc53cb17dcd2xc","column":60,"index":"2","jfgird_select_save":[],"rh_height":1790,"visibledatacolumn":[],"scrollTop":0,"block_id":"fblock","rowsplit":[],"visibledatarow":[],"jfgrid_selection_range":{},"name":"Sheet2","ch_width":4748,"row":84,"scrollLeft":0,"id":350081777752215553,"chart":[],"config":{},"order":1,"status":0},{"color":"","list_id":"1079500#-8803#7c45f52b7d01486d88bc53cb17dcd2xc","column":60,"index":"3","jfgird_select_save":[],"rh_height":1790,"visibledatacolumn":[],"scrollTop":0,"block_id":"fblock","rowsplit":[],"visibledatarow":[],"jfgrid_selection_range":{},"name":"Sheet3","ch_width":4748,"row":84,"scrollLeft":0,"id":350081777752215554,"chart":[],"config":{},"order":2,"status":0}] 2,就会建websocket通信 ws://192.168.154.131:8888 $data1 = '{"message":"连接成功","type":"0","status":"0"}'; $data2 = '{"data":"","message":"反馈以前操作信息","type":"4","status":"0"}'; 发送个前端 这样就可以一share多人协作模式正常打开了 3,如果操作Luckysheet会触发 saveParam方法 通过 let msg = pako.gzip(encodeURIComponent(JSON.stringify(d)), { to: "string" }); if(_this.websocket!=null){ _this.websocket.send(msg); } 发送给服务端,这个是经过pako加密的,服务端需要先解开数据加密,然后根据 _this.saveParam("rv", sheetIndex, v, { "range": { "row": [str, edr], "column": [c1, c2] } }); if(i == n - 1){ _this.saveParam("rv_end", sheetIndex, null); } 告诉客户端返回不通过的status,需要查看 server.js的源代码 返回数据格式 { createTime: 命令发送时间 data:{} 修改的命令 id: "7a" websocket的id returnMessage: "success" status: "0" 0告诉前端需要根据data的命令修改 1无意义 type: 0:连接成功,1:发送给当前连接的用户,2:发送信息给其他用户,3:发送选区位置信息,999:用户连接断开 username: 用户名 } webman的时候需要返回这种格式的json给当前连接的客户端,然后广播给其他客户端,这样就完成了多人协作的基本功能 <?php namespace process; use Webman\Channel\Client; use Workerman\Connection\TcpConnection; use Workerman\Timer; class Luckysheet { protected $connections = []; public function __construct() { } public function onConnect(TcpConnection $connection) { echo "onConnect\n"; } public function onWebSocketConnect(TcpConnection $connection, $http_buffer) { echo "onWebSocketConnect\n"; $data1 = '{"message":"连接成功","type":"0","status":"0"}'; $connection->send($data1); $data2 = '{"data":"","message":"反馈以前操作信息","type":"4","status":"0"}'; $connection->send($data2); $key = $this->getUid($connection->getLocalIp(), $connection->getLocalPort(), $connection->worker->workerId, $connection->worker->id, $connection->id); $this->connections[$key] = $connection; } /* * { createTime: 命令发送时间 data:{} 修改的命令 id: "7a" websocket的id returnMessage: "success" status: "0" 0告诉前端需要根据data的命令修改 1无意义 type: 0:连接成功,1:发送给当前连接的用户,2:发送信息给其他用户,3:发送选区位置信息,999:用户连接断开 username: 用户名 } */ public function onMessage(TcpConnection $connection, $data) { $key = $this->getUid($connection->getLocalIp(), $connection->getLocalPort(), $connection->worker->workerId, $connection->worker->id, $connection->id); $return = []; $return['createTime'] = time(); $return['data'] = null; $return['returnMessage'] = 'success'; $return['status'] = '1'; $return['type'] = 0; $return['id'] = $key; $return['username'] = $key; if ($data == 'rub') { //心跳不回复 } else { //解析数据出错,目前不清楚是为什么,不能解析,就无法 给$return 返回对应的数据 $out = json_decode(urldecode(gzdecode($data)), true); //返回错误是 gzdecode data error //单线程版本写法,多线程需要channel通信 $this->broadcast($key, $out); $connection->send(json_encode($return)); } } public function onClose(TcpConnection $connection) { echo "onClose\n"; } public function getUid($local_ip, $local_port, $workerId, $worker_id, $connection_id) { $str = $local_ip . $local_port . $workerId . $worker_id . $connection_id; return md5($str); } public function broadcast($key, $data) { foreach ($this->connections as $k => $connection) { if ($k !== $key) { $connection->send($data); } } } } 目前在webman的websocket去解析 加密数据 但是在其他地方都可以解析出来 1,java版本解析没问题 2,laravel中 3,webman api模式 测试前端 const obj = [ { foo: 'bar', baz: 'baz' }, { abra: 1, cadabra: null } ] let msg = pako.gzip(encodeURIComponent(JSON.stringify(obj)), { to: "string" }); console.log(msg) function send(msg) { var xhr = new XMLHttpRequest; xhr.open('POST', 'http://www.yd.com/open/test', true); xhr.send(msg); //setTimeout(send, 5000); } send(msg); 后端代码基本一样 webman api $in = $request->rawBody(); $res = json_decode(urldecode(gzdecode($in)), true); return json($res); laravel $in = file_get_contents("php://input"); $res = json_decode(urldecode(gzdecode($in)), true); java版本的话,参考 https://gitee.com/chuanshanjun/luckysheet-saved-in-recovery