php ajax 长轮询 表单,php+ajax长轮询实现web即时聊天

web im的实现方式有很多种:

1.普通轮询,原理通过js定时重复发送ajax请求服务端,获取数据后显示.

2.长轮询,ajax请求服务端,服务端有数据会立即返回,服务端无数据时,会一直等待,直到有数据了才立即范围.

3.socket长连接.

特征分析:

方法1:实现起来最容易,定时重复请求服务端会产生无意义的http连接,消耗服务端资源,实时性较差.

方法2:实现起来较容易,会减少无效的ajax请求产生的http连接,能即时返回数据,但服务端会一直挂着,会消耗一定的资源,处理并发能力不强,比较适合于中小型应用服务.(comet)

方法3:门槛较高,需了解socket通讯协议,是php实现长连接的最佳方式,也是真正意义上的server push技术.

本文介绍第二种实现方法

案例名称:web即时聊天(ajax长轮询方式实现)

功能介绍:对话双方都在线(浏览器没有关闭的情况下),对话即时推算.

当一方不在线时,支持离线发送消息.当离线方上线时,会自动接收离线消息.

~~本项目只注重php服务端的实现机制和性能优化,前端界面粗糙请忽略.适合初中级php程序员学习借鉴,欢迎各位指教交流~~

预览

e59305cc92ba550fcdfe03a5a58d0863.png

项目文件结构:GetMessage.php

SendMessage.php

client.php

jquery.min.js

sql

准备工作:数据库mysql> desc message;

+-------------+------------------+------+-----+---------+----------------+

| Field       | Type             | Null | Key | Default | Extra          |

+-------------+------------------+------+-----+---------+----------------+

| id          | int(10)          | NO   | PRI | NULL    | auto_increment |

| reciver_uid | int(10) unsigned | NO   | MUL | 0       |                |

| sender_uid  | int(10) unsigned | NO   |     | 0       |                |

| content     | varchar(1000)    | NO   |     |         |                |

| create_time | int(10) unsigned | NO   |     | 0       |                |

| status      | tinyint(1)       | NO   |     | 0       |                |

+-------------+------------------+------+-----+---------+----------------+

客户端Client.php

实现功能:1.发送聊天信息,2获取并显示聊天内容

页面基本结构

功能1:发送内容操作

//-------------发送消息---------

$(function () {

var reciver_uid = <?php  echo $reciverUid;?>;

var sender_uid = <?php  echo $senderUid;?>;

$(‘#submit-message‘).on(‘click‘, function () {

var message_content = $(‘#message-box‘).val();

if (message_content != ‘‘) {

$(this).attr(‘disabled‘, ‘disabled‘);

var send_url = ‘./SendMessage.php‘;

var send_data = {

‘message‘: message_content,

‘reciver_uid‘: reciver_uid,

‘sender_uid‘: sender_uid,

};

$.post(send_url, send_data, function (response) {

if (response.status == 1) {

$(‘#message-box‘).val(‘‘);

$(‘#submit-message‘).removeAttr(‘disabled‘);

var send_message_str = ‘

‘;

send_message_str += ‘您对‘ + send_data.reciver_uid + ‘说:‘ + send_data.message;

send_message_str += ‘

‘;

$(‘#message-list‘).append(send_message_str);

} else {

console.log(‘发送失败!!‘);

}

}, ‘json‘);

}

});

});

处理发生消息SendMessage.php

实现功能:保存发送信息$link = mysqli_connect(

‘127.0.0.1‘,  /* The host to connect to 连接MySQL地址 */

‘root‘,      /* The user to connect as 连接MySQL用户名 */

‘‘,         /* The password to use 连接MySQL密码 */

‘web_im‘);    /* The default database to query 连接数据库名称*/

if (!$link) {

printf("Can‘t connect to MySQL Server. Errorcode: %s ", mysqli_connect_error());

exit;

}

//只能用函数来判断是否连接成功

if (mysqli_connect_errno()) {

echo mysqli_connect_error();

}

$senderUid = (int)$_POST[‘sender_uid‘];

$reciverUid = (int)$_POST[‘reciver_uid‘];

$message = str_replace([‘ ‘, ‘,‘], ‘‘, $_POST[‘message‘]);

$time = time();

$sql = "insert into message values(NULL ,‘{$reciverUid}‘,‘{$senderUid}‘,‘{$message}‘,‘{$time}‘,‘1‘)";

$result = mysqli_query($link, $sql);

$insertId = mysqli_insert_id($link);

if ($insertId) {

$returnArr = [‘status‘ => 1,‘info‘ => $insertId,];

} else {

$returnArr = [‘status‘ => 0,‘info‘ => ‘‘,];

}

echo json_encode($returnArr);

mysqli_close($link);

exit();

再回到客户端Client.php的功能2

功能2:获取并显示聊天内容(注意:客户端使用了递归跟服务端自动应答)

var reciver_uid = <?php  echo $senderUid;?>;

var sender_uid = <?php  echo $reciverUid;?>;

var url = ‘./GetMessage.php‘;

$(function () {

get_message_reply(url, reciver_uid, sender_uid, ‘get_message‘, ‘‘);

});

//获取消息并应答

//get_get_message_reply()

//param request_type  请求类型 详解:

//      get_message   获取信息

//      comfrim_read  确认已经读取了信息

function get_message_reply(url, reciver_uid, sender_uid, request_type, send_data) {

var setting = {

url: url,

data: {

‘request_type‘: request_type,

‘reciver_uid‘: reciver_uid,

‘sender_uid‘: sender_uid,

‘send_data‘: send_data,

},

type: ‘post‘,

dataType: ‘json‘,

success: function (response) {

if (response.status == 1) {

if (response.response_type == ‘is_read‘) {

//将消息写入到消息盒子

var messages = response.info;

var message_str = ‘‘;

var id_arr = new Array();

for (var i in messages) {

id_arr.push(messages[i][‘id‘]);

message_str += ‘

‘ + messages[i][‘sender_uid‘] + ‘在‘ + messages[i][‘send_time‘] + ‘的时候对您说:‘ + messages[i][‘content‘] + ‘‘;

}

$(‘#message-list‘).append(message_str);

//确认收到消息

get_message_reply(url, reciver_uid, sender_uid, ‘comfrim_read‘, id_arr);

} else if (response.response_type == ‘is_connecting‘) {

//继续获取消息

get_message_reply(url, reciver_uid, sender_uid, ‘get_message‘, ‘‘);

}

}

}

};

$.ajax(setting);

}

NOTICE:下面是核心中的核心

服务端推送消息GetMessage.phpset_time_limit(0);

$maxInvalidCount = 30;

$link = mysqli_connect(

‘127.0.0.1‘,  /* The host to connect to 连接MySQL地址 */

‘root‘,      /* The user to connect as 连接MySQL用户名 */

‘‘,         /* The password to use 连接MySQL密码 */

‘web_im‘);    /* The default database to query 连接数据库名称*/

if (!$link) {

printf("Can‘t connect to MySQL Server. Errorcode: %s ", mysqli_connect_error());

exit;

}

//只能用函数来判断是否连接成功

if (mysqli_connect_errno()) {

echo mysqli_connect_error();

}

$requestType = $_POST[‘request_type‘];

switch ($requestType) {

case ‘get_message‘://客户端请求读取消息

break;

case ‘comfrim_read‘://客户端确认已经读取了信息,服务端需要更新读取状态

$idsArr = $_POST[‘send_data‘];

$ids = implode(‘,‘, $idsArr);

$sql = "update message set status = 2 where id in ({$ids})";

mysqli_query($link, $sql);

mysqli_close($link);

break;

default:

break;

}

$sql = "select * from message where reciver_uid=‘{$_POST[‘reciver_uid‘]}‘ and sender_uid=‘{$_POST[‘sender_uid‘]}‘ and status=‘1‘";

$i = 0;

while (true) {

//读取数据

$result = mysqli_query($link, $sql);

if ($result) {

$returnArr = [];

while ($row = mysqli_fetch_assoc($result)) {

$row[‘send_time‘] = date(‘Y-m-d H:i:s‘, $row[‘create_time‘]);

$returnArr[] = $row;

}

if (!empty($returnArr)) {

//返回结果

$data = [

‘status‘ => 1,

‘response_type‘ => ‘is_read‘,

‘info‘ => $returnArr,

];

echo json_encode($data);

mysqli_free_result($result);

mysqli_close($link);

exit();

}

}

$i++;

//需要给客户端发送确认信息是否还在连接服务器,客户端无回应则整个过程结束

if ($i == $maxInvalidCount) {

$data = [

‘status‘ => 1,

‘response_type‘ => ‘is_connecting‘,

‘info‘ => ‘‘,

];

echo json_encode($data);

mysqli_close($link);

exit();

}

//file_put_contents(‘./test.log‘, date(‘Y-m-d H:i:s‘) . "已经执行了{$i}次" . "\r\n", FILE_APPEND);

sleep(1);

}

原文:http://phpme.blog.51cto.com/663593/1890859

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值