一.概述
在移动开发领域有弹性交友这样一种类型的交友产品,其代表就是陌陌,遇见通过LBS找附近的周边的陌生人,那么在访问网页内容的时候特别是看视频,新闻,漫画,博客时和正在访问的用户进行交流聊天,这种类型的产品就是基于页面的弹性交友工具。说道弹性交友肯定就是需要找到附近的用户,那么附近的用户也许现在并不想被打扰,所以弹性交友工具有时也会给用户带来烦恼,基于这样一个诉求,在访问某个个网站时也许你并不想被打搅那么是否与别人交流的控制权完全的掌握在用户的手中。
二.实现技术
实现技术并不是很复杂的技术,主要使用到的是WebSocket API, tomcat 7.40 , java Servlet ,memcached,tomcat7.26后就开始支持WebSocket API,只需要按照规范开发专用的Servlet程序就可以轻松的实现WebSocket的服务功能接收发送文本或者流数据(可以用来实现网页版的大文件上传)。整个系统由负载均衡服务器,HTTP服务器WebSocket服务器,分布式缓存组成。用户访问时通过HTTP负载均衡服务器找到由Servlet编写的WebSocket负载服务器,有WebSocket负载服务器将用户连接发送到指定的WebSocket服务器上。在后期将会加入文件服务器,HTML5支持流文件访问形式,通过和WebSocket结合使用可是实现聊天中发送附件的功能(v 0.2)实现。
服务架构图
用户可以通过任何嵌入了客户端代码的网站访问聊天室,聊天室根据不同网站的域名来实现对用户分区,只有访问相同网站的用户才能收到同网站用户发送的消息。
三.网站如何使用
对于一个网站可以通过云方式访问,也可以下载源代码将服务器端部署到tomcat里面,然后网页中嵌入JS代码便能够实现网站弹性交友聊天功能。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>chat</title>
<link href="style/dialog.css" rel="stylesheet" type="text/css" />
</head>
<script src="js/jquery-1.10.0.min.js"></script>
<script src="js/jquery-migrate-1.2.1.min.js"></script>
<script src="js/chat.js"></script>
<body>
</body>
</html>
测试网页代码
客户端程序必须要导入JQuery库,由于开发时间问题没有使用原生态的JS来实现,如果真的应用到商业领域必须将客户端代码改为用原生的JS代码
var HEADER = "<===header===>";
var BODY = "<===body===>";
var RESPONSE = "<===response===>";
var ws = null;
var isAll = true;
var task = null;
var name = '';
var chatKey = '';
var username = "";
var domain = "";
var ipaddre = "";
$(document)
.ready(
function() {
init();
function init() {
var bodyContent = $("body").html();
bodyContent += "<div id=\"chatBtn\" class=\"btn-class\"><button id=\"showDialog\">对话</button></div><div id=\"dialog\" class=\"dialog-class\"><p><button id=\"hideDialog\">关闭</button></p><div style=\"display:inline;\"><div class=\"msg-class\"><textarea id=\"viewsMsg\" cols=\"28\" rows=\"6\" disabled=\"disabled\"></textarea></div><div class=\"member-class\"><select id=\"memberList\" size=\"10\" style=\"width:130px\"><option value=\"\">ALL</option></select></div></div><div><textarea id=\"privateMsg\" cols=\"28\" rows=\"3\" disabled=\"disabled\"></textarea></div><div><textarea id=\"msg\" cols=\"32\" rows=\"1\"></textarea><button id=\"send\">Send</button></div></div>";
$("body").html(bodyContent);
$.ajax({
type:'get',
url:'/web/route',
dataType:'text',
success:function(data){
ipaddre = "ws://" + data + "/web/chat";
alert(ipaddre);
},error : function(){
alert('异常');
}
});
}
;
$("#dialog").hide();
$("#showDialog").click(function() {
$("#dialog").show();
$("#dialog").css("top", 10);
$("#dialog").css("left", 30);
$("#chatBtn").hide();
initWebSocket();
});
$("#hideDialog").click(function() {
$("#dialog").hide();
var closeData = "CLOSE" + HEADER + domain + BODY + name;
sendMsg(closeData);
$("#chatBtn").show();
if (task) {
clearInterval(task);
}
});
$("#send").click(
function() {
var msg = $("#msg").val();
var chatData = "";
if (isAll) {
var value = $("#viewsMsg").text();
value += "您说:" + msg + "\n";
$("#viewsMsg").text(value);
chatData = "MSGBRODACAST" + HEADER + domain + BODY + name
+ BODY + msg;
} else {
var value = $("#privateMsg").text();
value += "您说:" + msg + "\n";
$("#privateMsg").text(value);
chatData = "MSGPRIVATE" + HEADER + domain + BODY + name
+ BODY + username + BODY + msg;
}
sendMsg(chatData);
$("#msg").val("");
});
$("#memberList").click(
function() {
username = $("#memberList").find(
"option:selected").text();
if (username != 'ALL') {
isAll = false;
} else {
isAll = true;
}
});
});
function initWebSocket() {
//ws = new WebSocket("ws://localhost:8080/web/chat");
ws = new WebSocket(ipaddre);
$("#msg").text("建立连接中");
ws.onopen = function() {
var tip = "请输入您的名字";
name = prompt(tip);
if (name == null) {
name = "NULL";
}
domain = getURL();
var connectData = "CONNECT" + HEADER + name + BODY + domain;
sendMsg(connectData);
$("#msg").text("");
task = setInterval(function() {
var keepaliveData = "KEEPALIVE" + HEADER + domain + BODY + name;
sendMsg(keepaliveData);
}, 1000);
};
ws.onmessage = function(event) {
var values = event.data.split(RESPONSE);
if (values[0] == 'KEEPALIVE') {
}
if (values[0] == 'MSGBRODACAST') {
var value = $("#viewsMsg").text();
alert(values[1]);
var msgData = values[1].split(BODY);
var msgId = msgData[0];
value += msgData[1] + "\n";
$("#viewsMsg").text(value);
var feedback = "FEEDBACK" + HEADER + domain + BODY + msgId + BODY + name;
alert(feedback);
sendMsg(feedback);
}
if (values[0] == 'MEMBERLIST') {
value = values[1];
$("#memberList").empty();
$("#memberList").append("<option value=\"\">ALL</option>" + value);
}
if (values[0] == 'SUCCESS') {
if (name == "NULL") {
name = values[1];
}
}
if (values[0] == 'MSGPRIVATE') {
var value = $("#privateMsg").text();
var msgData = values[1].split(BODY);
var msgId = msgData[0];
value += msgData[1] + "\n";
$("#privateMsg").text(value);
var feedback = "FEEDBACK" + HEADER + domain + BODY + msgId + BODY + name;
sendMsg(feedback);
}
};
}
function sendMsg(data) {
ws.send(data);
}
function getURL(){
var curWebPath = window.document.location.href;
//获取主机地址之后的目录,如: cis/website/meun.htm
var pathName = window.document.location.pathname;
var pos = curWebPath.indexOf(pathName); //获取主机地址,如: http://localhost:8080
var localhostPaht = curWebPath.substring(0, pos); //获取带"/"的项目名,如:/cis
var projectName = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
var rootPath = localhostPaht + projectName;
return rootPath;
}
项目下载地址
现在项目是开发阶段还有很多功能有待完善还有很多BUG没有解决如果有兴趣参与开发的可以邮寄联系我或者加我的MSN
reaganjava@hotmail.com