求问 我的Workerman 在服务器上一直连接不上
自己在本地部署的时候可以连接, 一直报错 Cannot assign requested address in 无法在中分配请求的地址,我把 php.ini 里面的禁用函数都删了,还是连不上。把连接的 IP 换成服务器的公网IP,私网IP都不行,不知道是哪里问题
在存储聊天记录里面有exit函数,看文档exit函数也会有影响,不知道是不是这边
服务端代码
<!DOCTYPE html>
<html>
<head>
<title>"百度商桥"--客服端</title>
<link rel="stylesheet" type="text/css" href="/static/plugins/layui/css/layui.css">
<script type="text/javascript" src="/static/plugins/layui/layui.js"></script>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<style>
.container{
border:1px solid #cdcdcd;width: 800px;height: 500px;
}
.member-list{
padding:5px;border-right: 1px solid #cdcdcd; width: 200px;
height: 500px;float: left;box-sizing: border-box;
}
.msg-container{
width: 599px;height: 500px;float: left;
}
.msg-list{
height: 400px;border-bottom: 1px solid #cdcdcd;
}
.msg-list .msg-item{
border:1px solid #cdcdcd;
border-radius: 4px;
padding: 5px 10px;
background: #f1f1f1;
margin-bottom: 5px;
}
.msg-send{
outline: none;padding: 10px; height: 100px;
}
.member-item{
/*border-radius: 1px #f1f1f1;*/
padding: 5px 10px;
background:#f1f1f1;
border-radius: 4px;
margin-bottom: 5px;
}
.active{
background: #1E9FFF;
color: #fff;
}
.msg-me{
text-align: right;
background: #5FB878!important;
color: #fff;
}
</style>
</head>
<body style="padding:10px">
<div class="container">
<div class="member-list"></div>
<div class="msg-container">
<div class="msg-list"></div>
<div class="msg-send" id="id1" contenteditable="true"></div>
</div>
<button type="button" class="layui-btn" style="float:right;margin-top:10px" onclick="sendmsg()">发送</button>
</div>
</body>
</html>
<script type="text/javascript">
var user_list = [];
layui.use('layer',function(){
layer = layui.layer;
// $ = layui.jquery;
});
ws = new WebSocket("ws://127.0.0.1:2000");
ws.onopen = function() {
var data = {};
data.type = 'login';
data.group = 'admin';
ws.send(JSON.stringify(data));
// console.log(JSON.stringify(data));
// 拉取用户列表
init_load_user_list();
};
ws.onmessage = function(e) {
var data = JSON.parse(e.data);
console.log(data);
// 新客户要进来了
if(data.type == 'login'){
if($.inArray(data.from_id,user_list) == -1){
user_list.push(data.from_id);
}
build_servicer_user_list();
return;
}
// 客户连接断开
if(data.type == 'logout'){
var index = $.inArray(data.conn_id,user_list);
if(index > -1){
user_list.splice(index,1);
}
build_servicer_user_list();
return;
}
if(data.type == 'load_user_list'){
var userlist = data.userlist;
$.each(userlist,function(i,v){
user_list.push(v);
});
build_servicer_user_list();
return;
}
var msg_member_list = $('#member_'+data.from_id);
if(msg_member_list.length==0){
var html_container = '<div id="member_'+data.from_id+'"></div>';
$('.msg-list').append(html_container);
}
var html = '<div class="msg-item">\
<div class="nickname">客户:'+data.from_id+'说:</div>\
<div>'+data.msg+'</div>\
</div>';
$('#member_'+data.from_id).append(html);
$('#member_'+data.from_id).show().siblings('div').hide();
};
// 构建客服端的客户列表
function build_servicer_user_list(){
var html = '';
$.each(user_list,function(i,v){
html += ('<div class="member-item" onclick="checkme(this)" member_id="'+v+'">客户:'+v+'</div>')
});
$('.member-list').html(html);
}
// 消息发送
function sendmsg(){
var touid = parseInt($('.member-list div[class*="active"]').attr('member_id'));
// console.log(member_id);
if(isNaN(touid)){
return layer.alert('请选择客户~',{icon:2});
}
var msg = $('.msg-send').html();
var data = {};
data.type = 'msg';
data.group = 'admin';
data.touid = touid;
data.msg = $('.msg-send').html();
ws.send(JSON.stringify(data));
$('.msg-send').html('');
var html = '<div class="msg-item msg-me">\
<div class="nickname">我说:</div>\
<div>'+data.msg+'</div>\
</div>'
$('.msg-list').append(html);
}
// 拉取用户列表
function init_load_user_list(){
var data = {};
data.type = 'load_user_list';
data.group = 'admin';
ws.send(JSON.stringify(data));
}
// 和某个客户聊天
function checkme(obj){
$(obj).addClass('active').siblings('div').removeClass('active');
var member_id = $(obj).attr('member_id');
$('#member_'+member_id).show().siblings('div').hide();
}
</script>
客户端
<!DOCTYPE html>
<html>
<head>
<title>CSS中单位px、rem、em浅析</title>
<link rel="stylesheet" type="text/css" href="/static/plugins/layui/css/layui.css">
<script type="text/javascript" src="/static/plugins/layui/layui.js"></script>
</head>
<body>
<div style="color: #333;padding: 20px;">
绝对长度
px
px是像素值,是一个固定的长度,比如我们的米,厘米一样。
相对长度
为什么我们需要相对长度rem em等?
固定长度已经不能满足我们现在的需求了。
举例:比如我们在缩小我们屏幕的时候,我们不仅仅是需要缩小我们的盒子的宽高,我们还想要让我们字体大小也随之缩小,这样用户体验会更好一点。
rem
rem 与 px 的计算关系
rem的值是px的倍数
默认情况下font-size = 16px,那么1rem = 16px
rem 如何修改与px的相对计算关系
我们可以在并且只能在html标签(因为html节点是根节点,就是rem里面的r:root)里面修改font-size : 32px, 从而1rem = 32px
</div>
</body>
</html>
<script type="text/javascript">
layui.use('layer',function(){
layer = layui.layer;
$ = layui.jquery;
init_bdbuss()
});
function init_bdbuss(){
layer.open({
type: 2,
title: ' php 中文网欢迎你',
shadeClose: true,
shade: 0.3,
area: ['580px', '70%'],
content: '/bdbuss/index', //iframe的url
btn:['发送'],
yes: function(index,layero){
var body = layer.getChildFrame('body', index);
var iframeWin = window[layero.find('iframe')[0]['name']]; //得到iframe页的窗口对象,执行iframe页的方法:
iframeWin.send();
}
});
}
</script>
存储聊天信息页面
1.curl 页面代码
<?php
namespace App\Http\Controllers\admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
// 管理员列表
class Pya extends Controller
{
public function save(){
$posts = ['from_uid'=>1,'to_uid'=>2,'msg'=>435465];
// $k=http_build_query($posts);
$url = 'http://lal1.php/admin/kfmsg/ave_msg';
// var_dump($k);
// http_build_query($posts);
// $res =$this->curl_post($url,$posts);
// $header = array('Content-Type: application/x-www-form-urlencoded; charset=UTF-8');
$header = array('Content-Type: application/x-www-form-urlencoded; charset=UTF-8');
$res = $this->httpRequest($url,'POST',$posts,$header);
var_dump($res);
// exit();
}
// $url 是请求的链接
// $postdata 是传输的数据,数组格式
function httpRequest($url, $method = 'GET', $postfields = null, $headers = array(), $debug = false) {
/* $Cookiestr = ""; * cUrl COOKIE处理*
if (!empty($_COOKIE)) {
foreach ($_COOKIE as $vk => $vv) {
$tmp[] = $vk . "=" . $vv;
}
$Cookiestr = implode(";", $tmp);
} */
$method = strtoupper($method);
$ci = curl_init();
/* Curl settings */
curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间,如果设置为0,则无限等待 */
curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */
curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
switch ($method) {
case "POST":
curl_setopt($ci, CURLOPT_POST, true);
if (!empty($postfields)) {
$tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
}
break;
default:
curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */
break;
}
$ssl = preg_match('/^https:\/\//i', $url) ? TRUE : FALSE;
curl_setopt($ci, CURLOPT_URL, $url);
if ($ssl) {
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
}
//curl_setopt($ci, CURLOPT_HEADER, true); /*启用时会将头文件的信息作为数据流输出*/
curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ci, CURLOPT_MAXREDIRS, 2); /* 指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的 */
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ci, CURLINFO_HEADER_OUT, true);
/* curl_setopt($ci, CURLOPT_COOKIE, $Cookiestr); * *COOKIE带过去** */
$response = curl_exec($ci);
$requestinfo = curl_getinfo($ci);
$http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
if ($debug) {
echo "=====post data======\r\n";
var_dump($postfields);
echo "=====info===== \r\n";
print_r($requestinfo);
echo "=====response=====\r\n";
print_r($response);
}
curl_close($ci);
return array($http_code, $response, $requestinfo);
}
}
2.后端业务逻辑
<?php
namespace App\Http\Controllers\admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class Kfmsg extends Controller
{
public function save_msg(Request $request)
{
$data['from_id'] = (int)$request->from_uid;
$data['to_uid'] = (int)$request->to_uid;
$data['msg'] = trim($request->msg);
$data['add_time'] = time();
if($data['from_id']==0 || $data['to_uid']==0){
exit(json_encode(array('code'=>1,'msg'=>'参数错误')));
}
DB::table('kefumsg')->insert($data);
exit(json_encode(array('code'=>0,'msg'=>'保存成功~')));
}
//
// public function save_msg(Request $request)
// {
// $data['from_uid'] = 1;
// $data['to_uid'] = 2;
// $data['msg'] ='hdsalkhd';
// $data['add_time'] = time();
// if($data['from_uid']==0 || $data['to_uid']==0){
// exit(json_encode(array('code'=>1,'msg'=>'参数错误')));
// }
// DB::table('kefumsg')->insert($data);
// exit(json_encode(array('code'=>0,'msg'=>'保存成功~')));
// }
}
除了输出视图的方法没有贴,其他代码全部贴上了,自己本地测试没有问题,服务器上面就没有办法连接
谢谢各位大佬,菜鸟一个,多多指教
workmam 代码
<?php
use Workerman\Worker;
use \Workerman\Lib\Timer;
require_once __DIR__ . '/workerman/Autoloader.php';
// 注意:这里与上个例子不同,使用的是websocket协议
$ws_worker = new Worker("websocket://0.0.0.0:2000");
// 启动4个进程对外提供服务
$ws_worker->count = 4;
// 当收到客户端发来的数据后返回hello $data给客户端
$ws_worker->onMessage = function($connection, $data)
{
global $ws_worker;
var_dump($connection->id);
// return;
// 向客户端发送hello $data
// $connection->send($data);
//
$data = json_decode($data,true);
// print_r($data);
if($data['type'] == 'login'){
$connection->group = $data['group'];
// 当客户登录时,随机分配一个客服
if($data['group'] == 'member'){
$admin_list = [];
foreach ($ws_worker->connections as $conn ) {
// var_dump($conn->group);
if($conn->group == 'admin'){
$admin_list[] = $conn->id;
}
}
$index = array_rand($admin_list,1);
$connection->touid = $admin_list[$index];
// 通知这位客服有新用户进来
foreach($ws_worker->connections as $conn)
{
if($connection->touid == $conn->id){
$data['from_id'] = $connection->id;
$conn->send(json_encode($data));
}
}
}
// $connection->send(json_encode($data));
}
if($data['type'] == 'msg'){
if($connection->group == 'member'){
foreach($ws_worker->connections as $conn)
{
if($connection->touid == $conn->id){
$data['from_id'] = $connection->id;
// $conn->send("user[{$connection->uid}] said: $data");
$conn->send(json_encode($data));
// print_r($data);
}
}
}
if($connection->group == 'admin'){
$touid = $data['touid'];
foreach($ws_worker->connections as $conn)
{
if($touid == $conn->id){
$msgData = [];
$msgData['type'] = 'msg';
$msgData['from_uid'] = $connection->id;
$msgData['msg'] = $data['msg'];
$conn->send(json_encode($msgData));
// $posts = [
// 'from_id'=>$connection->id,
// 'to_uid'=>$touid,
// 'msg'=>$data['msg']
// ];
// $posts = ['from_uid'=>1,'to_uid'=>2,'msg'=>435465];
$posts = ['from_uid'=>$connection->id,'to_uid'=>$touid,'msg'=>$data['msg']];
// print_r($posts);
// $url = 'http://lal1.php/admin/kfmsg/ave_msg';
// $k = http_build_query($posts);
// $res = $this->curl_post($url,$k);
// var_dump($res);
// $url = 'http://lal1.php/admin/kfmsg/ave_msg';
$url = 'http://lal1.php/admin/kfmsg/ave_msg';
// var_dump($k);
// http_build_query($posts);
// $res =$this->curl_post($url,$posts);
// $header = array('Content-Type: application/x-www-form-urlencoded; charset=UTF-8');
$res = curl_post($url,$posts);
var_dump($res);
}
}
}
}
if($connection->group == 'admin' && $data['type'] == 'load_user_list'){
$userlist = [];
foreach($ws_worker->connections as $conn)
{
if($conn->group == 'member'){
$userlist[] = $conn->id;
}
}
$data['type'] = 'load_user_list';
$data['userlist'] = $userlist;
$connection->send(json_encode($data));
}
// 转发给所有人
// global $ws_worker;
// foreach($ws_worker->connections as $conn)
// {
// // $conn->send("user[{$connection->uid}] said: $data");
// $conn->send($data);
// }
};
// 断开连接
$ws_worker->onClose = function($connection){
global $ws_worker;
foreach ($ws_worker->connections as $conn ) {
if($conn->group == 'admin'){
$data = [];
$data['type'] = 'logout';
$data['conn_id'] = $connection->id;
$conn->send(json_encode($data));
}
}
// echo "connection closed\n";
};
// 定义一个http函数
function curl_post( $url, $postdata ) {
$header = array(
'Accept: application/json',
);
//初始化
$curl = curl_init();
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, $url);
//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// 超时设置
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
// 超时设置,以毫秒为单位
// curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);
// 设置请求头
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE );
//设置post方式提交
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
//执行命令
$data = curl_exec($curl);
// 显示错误信息
if (curl_error($curl)) {
print "Error: " . curl_error($curl);
} else {
// 打印返回的内容
var_dump($data);
curl_close($curl);
}
}
// 运行worker
Worker::runAll();
推荐文章: