Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 30 additions & 184 deletions client.html
Original file line number Diff line number Diff line change
@@ -1,191 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<style>
p {
text-align: left;
padding-left: 20px;
}
</style>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat test page</title>
<link rel="stylesheet" type="text/css" href="css/looper_ui.css">
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>
<div style="width: 800px;height: 600px;margin: 30px auto;text-align: center">
<h1>websocket聊天室</h1>
<div style="width: 800px;border: 1px solid gray;height: 300px;">
<div style="width: 200px;height: 300px;float: left;text-align: left;">
<p><span>当前在线:</span><span id="user_num">0</span></p>
<div id="user_list" style="overflow: auto;">

</div>
</div>
<div id="msg_list" style="width: 598px;border: 1px solid gray; height: 300px;overflow: scroll;float: left;">
</div>
</div>
<br>
<textarea id="msg_box" rows="6" cols="50" onkeydown="confirm(event)"></textarea><br>
<input type="button" value="发送" onclick="send()">
<h2 class="describe">实时聊天室实现</h2>
<div class="view" id="app">
<div class="chat_list">
<h4 class="your_id">Your id is:{{ user_id }}</h4>
<h4 class="your_id">当前在线:{{ user_num }}人</h4>
<h4 v-for="user in user_list" class="your_id">{{ user }}</h4>

</div>
<div class="history">
<div class="history_box">
<p v-for="item in hist" class="msg other_msg">{{item}}<br></p>

</div>
<div class="msg_box">
<input type="text" name="" v-model="message" class="text_input" @keyup.13="send_my_msg" placeholder="请输入内容……"></div>
<button class="send_btn" v-on:click="send_my_msg">发送(Enter)</button>
</div>
</div>
</body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript" src="js/axios.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<style type="text/css">

</style>
</html>

<script type="text/javascript">
// 存储用户名到全局变量,握手成功后发送给服务器
var uname = prompt('请输入用户名', 'user' + uuid(8, 16));
var ws = new WebSocket("ws://127.0.0.1:8080");
ws.onopen = function () {
var data = "系统消息:建立连接成功";
listMsg(data);
};

/**
* 分析服务器返回信息
*
* msg.type : user 普通信息;system 系统信息;handshake 握手信息;login 登陆信息; logout 退出信息;
* msg.from : 消息来源
* msg.content: 消息内容
*/
ws.onmessage = function (e) {
var msg = JSON.parse(e.data);
var sender, user_name, name_list, change_type;

switch (msg.type) {
case 'system':
sender = '系统消息: ';
break;
case 'user':
sender = msg.from + ': ';
break;
case 'handshake':
var user_info = {'type': 'login', 'content': uname};
sendMsg(user_info);
return;
case 'login':
case 'logout':
user_name = msg.content;
name_list = msg.user_list;
change_type = msg.type;
dealUser(user_name, change_type, name_list);
return;
}

var data = sender + msg.content;
listMsg(data);
};

ws.onerror = function () {
var data = "系统消息 : 出错了,请退出重试.";
listMsg(data);
};

/**
* 在输入框内按下回车键时发送消息
*
* @param event
*
* @returns {boolean}
*/
function confirm(event) {
var key_num = event.keyCode;
if (13 == key_num) {
send();
} else {
return false;
}
}

/**
* 发送并清空消息输入框内的消息
*/
function send() {
var msg_box = document.getElementById("msg_box");
var content = msg_box.value;
var reg = new RegExp("\r\n", "g");
content = content.replace(reg, "");
var msg = {'content': content.trim(), 'type': 'user'};
sendMsg(msg);
msg_box.value = '';
// todo 清除换行符
}

/**
* 将消息内容添加到输出框中,并将滚动条滚动到最下方
*/
function listMsg(data) {
var msg_list = document.getElementById("msg_list");
var msg = document.createElement("p");

msg.innerHTML = data;
msg_list.appendChild(msg);
msg_list.scrollTop = msg_list.scrollHeight;
}

/**
* 处理用户登陆消息
*
* @param user_name 用户名
* @param type login/logout
* @param name_list 用户列表
*/
function dealUser(user_name, type, name_list) {
var user_list = document.getElementById("user_list");
var user_num = document.getElementById("user_num");
while(user_list.hasChildNodes()) {
user_list.removeChild(user_list.firstChild);
}

for (var index in name_list) {
var user = document.createElement("p");
user.innerHTML = name_list[index];
user_list.appendChild(user);
}
user_num.innerHTML = name_list.length;
user_list.scrollTop = user_list.scrollHeight;

var change = type == 'login' ? '上线' : '下线';

var data = '系统消息: ' + user_name + ' 已' + change;
listMsg(data);
}

/**
* 将数据转为json并发送
* @param msg
*/
function sendMsg(msg) {
var data = JSON.stringify(msg);
ws.send(data);
}

/**
* 生产一个全局唯一ID作为用户名的默认值;
*
* @param len
* @param radix
* @returns {string}
*/
function uuid(len, radix) {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
var uuid = [], i;
radix = radix || chars.length;

if (len) {
for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
} else {
var r;

uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';

for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random() * 16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}

return uuid.join('');
}
</script>
Loading