H5+MUI+Node.js+Socket.io实现即时聊天以及发送+图片压缩

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<title></title>
		<link href="css/mui.min.css" rel="stylesheet" />
		<!--<link rel="stylesheet" type="text/css" href="css/app.css" />-->
		<link href="css/mui.imageviewer.css" rel="stylesheet" />//发送图片后,点击图片大图预览用的
		<link rel="stylesheet" href="css/iconfont.css">

		<!–[if lt IE 8]><script src="js/json3.js"></script><![endif]–>
		<style type="text/css">
			.mui-bar-nav {
				background-color: #00abed;
				-webkit-box-shadow: none;
				box-shadow: none;
			}
			.mui-bar {
				height: 80px;
				line-height: 80px;
			}
			.mui-title {
				color: #fff;
				font-weight: bold;
			}
			.msg-my-img{
				float: right;
				width: 38px;
				height: 38px;
				border-radius: 3px;
				color: #ddd;
				vertical-align: top;
				text-align: center;
			}
		</style>
		<style>
			html,
			body {
				height: 100%;
				margin: 0px;
				padding: 0px;
				overflow: hidden;
				-webkit-touch-callout: none;
				-webkit-user-select: none;
			}
			footer {
				position: fixed;
				width: 100%;
				height: 50px;
				min-height: 50px;
				border-top: solid 1px #bbb;
				left: 0px;
				bottom: 0px;
				overflow: hidden;
				padding: 0px 50px;
				background-color: #fafafa;
			}
			.footer-left {
				position: absolute;
				width: 50px;
				height: 50px;
				left: 0px;
				bottom: 0px;
				text-align: center;
				vertical-align: middle;
				line-height: 100%;
				padding: 12px 4px;
			}
			.footer-right {
				position: absolute;
				width: 50px;
				height: 50px;
				right: 0px;
				bottom: 0px;
				text-align: center;
				vertical-align: middle;
				line-height: 100%;
				padding: 12px 5px;
				padding-top:15px;
				display: inline-block;
			}
			.footer-center {
				height: 100%;

				padding: 5px 0px;
				position: absolute;
				left:50px;
				right: 50px;
			}
			.footer-center [class*=input] {
				width: 100%;
				height: 100%;
				border-radius: 5px;
			}
			.footer-center .input-text {
				background: #fff;
				border: solid 1px #ddd;
				padding: 10px !important;
				font-size: 16px !important;
				line-height: 18px !important;
				font-family: verdana !important;
				overflow: hidden;
			}
			.footer-center .input-sound {
				background-color: #eee;
			}
			.mui-content {
				height: 100%;
				padding: 44px 0px 50px 0px;
				overflow: auto;
				background-color: #eaeaea;
			}
			#msg-list {
				height: 100%;
				overflow: auto;
				-webkit-overflow-scrolling: touch;
			}
			.msg-item {
				padding: 8px;
				clear: both;
			}
			.msg-item .mui-item-clear {
				clear: both;
			}
			.msg-item .msg-user {
				width: 38px;
				height: 38px;
				border: solid 1px #d3d3d3;
				display: inline-block;
				background: #fff;
				border-radius: 3px;
				vertical-align: top;
				text-align: center;
				float: left;
				padding: 3px;
				color: #ddd;
			}

			.msg-item .msg-user-img{
				width: 38px;
				height: 38px;
				display: inline-block;
				border-radius: 3px;
				vertical-align: top;
				text-align: center;
				float: left;
				color: #ddd;
			}

			.msg-item .msg-content {
				display: inline-block;
				border-radius: 5px;
				border: solid 1px #d3d3d3;
				background-color: #FFFFFF;
				color: #333;
				padding: 8px;
				vertical-align: top;
				font-size: 15px;
				position: relative;
				margin: 0px 8px;
				max-width: 75%;
				min-width: 35px;
				float: left;
				word-break:break-all;
			}
			.msg-item .msg-content .msg-content-inner {
				overflow-x: hidden;
			}
			.msg-item .msg-content .msg-content-arrow {
				position: absolute;
				border: solid 1px #d3d3d3;
				border-right: none;
				border-top: none;
				background-color: #FFFFFF;
				width: 10px;
				height: 10px;
				left: -5px;
				top: 12px;
				-webkit-transform: rotateZ(45deg);
				transform: rotateZ(45deg);
			}
			.msg-item-self .msg-user,
			.msg-item-self .msg-content {
				float: right;
			}
			.msg-item-self .msg-content .msg-content-arrow {
				left: auto;
				right: -5px;
				-webkit-transform: rotateZ(225deg);
				transform: rotateZ(225deg);
			}
			.msg-item-self .msg-content,
			.msg-item-self .msg-content .msg-content-arrow {
				background-color: #4CD964;
				color: #fff;
				border-color: #2AC845;
				word-break:break-all;
			}
			footer .mui-icon {
				color: #000;
			}
			footer .mui-icon:active {
				color: #007AFF !important;
			}
			footer .mui-icon-paperplane:before {
				content: "发送";
			}
			footer .mui-icon-paperplane {
				/*-webkit-transform: rotateZ(45deg);
				transform: rotateZ(45deg);*/

				font-size: 16px;
				word-break: keep-all;
				line-height: 100%;
				padding-top: 6px;
				color: rgba(0, 135, 250, 1);
				font-style: normal;
			}
			#msg-sound {
				-webkit-user-select: none !important;
				user-select: none !important;
			}
			.rprogress {
				position: absolute;
				left: 50%;
				top: 50%;
				width: 140px;
				height: 140px;
				margin-left: -70px;
				margin-top: -70px;
				background-image: url(../images/arecord.png);
				background-repeat: no-repeat;
				background-position: center center;
				background-size: 30px 30px;
				background-color: rgba(0, 0, 0, 0.7);
				border-radius: 5px;
				display: none;
				-webkit-transition: .15s;
			}
			.rschedule {
				background-color: rgba(0, 0, 0, 0);
				border: 5px solid rgba(0, 183, 229, 0.9);
				opacity: .9;
				border-left: 5px solid rgba(0, 0, 0, 0);
				border-right: 5px solid rgba(0, 0, 0, 0);
				border-radius: 50px;
				box-shadow: 0 0 15px #2187e7;
				width: 46px;
				height: 46px;
				position: absolute;
				left: 50%;
				top: 50%;
				margin-left: -23px;
				margin-top: -23px;
				-webkit-animation: spin 1s infinite linear;
				animation: spin 1s infinite linear;
			}
			.r-sigh{
				display: none;
				border-radius: 50px;
				box-shadow: 0 0 15px #2187e7;
				width: 46px;
				height: 46px;
				position: absolute;
				left: 50%;
				top: 50%;
				margin-left: -23px;
				margin-top: -23px;
				text-align: center;
				line-height: 46px;
				font-size: 40px;
				font-weight: bold;
				color: #2187e7;
			}
			.rprogress-sigh{
				background-image: none !important;
			}
			.rprogress-sigh .rschedule{
				display: none !important;
			}
			.rprogress-sigh .r-sigh{
				display: block !important;
			}
			.rsalert {
				font-size: 12px;
				color: #bbb;
				text-align: center;
				position: absolute;
				border-radius: 5px;
				width: 130px;
				margin: 5px 5px;
				padding: 5px;
				left: 0px;
				bottom: 0px;
			}
			@-webkit-keyframes spin {
				0% {
					-webkit-transform: rotate(0deg);
				}
				100% {
					-webkit-transform: rotate(360deg);
				}
			}
			@keyframes spin {
				0% {
					transform: rotate(0deg);
				}
				100% {
					transform: rotate(360deg);
				}
			}
			#h {
				background: #fff;
				border: solid 1px #ddd;
				padding: 10px !important;
				font-size: 16px !important;
				font-family: verdana !important;
				line-height: 18px !important;
				overflow: visible;
				position: absolute;
				left: -1000px;
				right: 0px;
				word-break: break-all;
				word-wrap: break-word;
			}
			.cancel {
				background-color: darkred;
			}
		</style>
	</head>

	<body contextmenu="return false;">
		<header class="mui-bar mui-bar-nav">
			<div style="margin-top:30px;">
			<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left" style="color: #fff;font-size: 26px;"></a>
			<h1 class="mui-title"><span id="name"></span></h1>
			</div>
		</header>
		<pre id='h'></pre>
		<script id='msg-template' type="text/template">
			<% for(var i in record){ var item=record[i]; %>
				<div class="msg-item <%= (item.sender=='self'?' msg-item-self':'') %>" msg-type='<%=(item.type)%>' msg-content='<%=(item.content)%>'>
					<div style="height: 30px;text-align: center;font-size: small;color: #a6a6a6;"><%=item.addtime %></div>
					<% if(item.sender=='self' ) { %>
						<!--<i class="msg-user mui-icon mui-icon-person"></i>-->
						<img class="msg-my-img" src="<%=item.upic%>" alt="" />
					<% } else { %>
						<img class="msg-user-img" src="<%=item.upic%>" alt="" />
					<% } %>
					<div class="msg-content">
						<div class="msg-content-inner">
							<% if(item.type=='text' ) { %>
								<%=( item.content|| '  ') %>
							<% } else if(item.type=='image' ) { %>
								<img class="msg-content-image" src="<%=(item.content)%>" style="max-width: 100px;" />
							<% } else if(item.type=='sound' ) { %>
								<span class="mui-icon iconfont icon-yuyin" style="font-size: 18px;font-weight: bold;"></span>
								<span class="play-state">点击播放</span>
							<% } %>
						</div>
						<div class="msg-content-arrow"></div>
					</div>
					<div class="mui-item-clear"></div>
				</div>
			<% } %>
		</script>
		<div class="mui-content" style="padding-top:70px;">
			<div id='msg-list'>
			</div>
		</div>
		<footer>
			<div class="footer-left">
				<i id='msg-image' class="mui-icon iconfont icon-paizhao" style="font-size: 28px;"></i>
			</div>
			<div class="footer-center">
				<textarea id='msg-text' type="text" class='input-text'></textarea>
				<button id='msg-sound' type="button" class='input-sound' style="display: none;">按住说话</button>
			</div>
			<label for="" class="footer-right">
				<i id='msg-type' class="mui-icon-paperplane"></i>
				<!--<i id='msg-type' class="mui-icon mui-icon-mic"></i>-->
			</label>
		</footer>
		<div id='sound-alert' class="rprogress">
			<div class="rschedule"></div>
			<div class="r-sigh">!</div>
			<div id="audio_tips" class="rsalert">手指上滑,取消发送</div>
		</div>
		<script src="js/mui.min.js"></script>
		<script src="js/mui.imageViewer.js"></script>
		<script src="js/arttmpl.js"></script>
		<script src="js/db.js"></script>//创建数据库的一些操作
		<script src="js/login.js" type="text/javascript" charset="utf-8"></script>//登录成功后记录的一些个人信息
		<script src="http://10.0.1.0:65535/socket.io/socket.io.js"></script>//服务端
		<script type="text/javascript" charset="utf-8">
			mui.init({
				beforeback:function(){
					localStorage.chartitem="none";
				}
			})

			var ws=null;
			var code,name,onlineUsers2;
			//var bindMsgList;
			(function($, doc) {
				var MIN_SOUND_TIME = 800;
				$.init({
					gestureConfig: {
						tap: true, //默认为true
						doubletap: true, //默认为false
						longtap: true, //默认为false
						swipe: true, //默认为true
						drag: true, //默认为true
						hold: true, //默认为false,不监听
						release: true //默认为false,不监听
					}
				});
				template.config('escape', false);
				$.plusReady(function() {
					//去掉滚动条
					plus.webview.currentWebview().setStyle({
						scrollIndicator: 'none'
					});
					ws = plus.webview.currentWebview();
					code = ws.account;//警号
					name=ws.name;//姓名
					localStorage.chartitem="show";

					document.getElementById("name").innerText=plus.webview.currentWebview().name;
					plus.webview.currentWebview().setStyle({
						softinputMode: "adjustResize"
					});
					var showKeyboard = function() {
						if ($.os.ios) {
							var webView = plus.webview.currentWebview().nativeInstanceObject();
							webView.plusCallMethod({
								"setKeyboardDisplayRequiresUserAction": false
							});
						} else {
							var Context = plus.android.importClass("android.content.Context");
							var InputMethodManager = plus.android.importClass("android.view.inputmethod.InputMethodManager");
							var main = plus.android.runtimeMainActivity();
							var imm = main.getSystemService(Context.INPUT_METHOD_SERVICE);
							imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);
							//var view = ((ViewGroup)main.findViewById(android.R.id.content)).getChildAt(0);
							imm.showSoftInput(main.getWindow().getDecorView(), InputMethodManager.SHOW_IMPLICIT);
						}
					};
					var record =[];
					var ui = {
						body: doc.querySelector('body'),
						footer: doc.querySelector('footer'),
						footerRight: doc.querySelector('.footer-right'),
						footerLeft: doc.querySelector('.footer-left'),
						btnMsgType: doc.querySelector('#msg-type'),
						boxMsgText: doc.querySelector('#msg-text'),
						boxMsgSound: doc.querySelector('#msg-sound'),
						btnMsgImage: doc.querySelector('#msg-image'),
						areaMsgList: doc.querySelector('#msg-list'),
						boxSoundAlert: doc.querySelector('#sound-console.log'),
						h: doc.querySelector('#h'),
						content: doc.querySelector('.mui-content')
					};
					ui.h.style.width = ui.boxMsgText.offsetWidth + 'px';
					//console.log(ui.boxMsgText.offsetWidth );
					var footerPadding = ui.footer.offsetHeight - ui.boxMsgText.offsetHeight;
					var msgItemTap = function(msgItem, event) {
						var msgType = msgItem.getAttribute('msg-type');
						var msgContent = msgItem.getAttribute('msg-content')
						if (msgType == 'sound') {
							player = plus.audio.createPlayer(msgContent);
							var playState = msgItem.querySelector('.play-state');
							playState.innerText = '正在播放...';
							player.play(function() {
								playState.innerText = '点击播放';
							}, function(e) {
								playState.innerText = '点击播放';
							});
						}
					};
					var imageViewer = new $.ImageViewer('.msg-content-image', {
						dbl: false
					});
					var bindMsgList = function() {
						//绑定数据:
						ui.areaMsgList.innerHTML = template('msg-template', {
							"record": record
						});
						var msgItems = ui.areaMsgList.querySelectorAll('.msg-item');
						[].forEach.call(msgItems, function(item, index) {
							item.addEventListener('tap', function(event) {
								msgItemTap(item, event);
							}, false);
						});
						imageViewer.findAllImage();
						setTimeout(function(){
							ui.areaMsgList.scrollTop = ui.areaMsgList.scrollHeight + ui.areaMsgList.offsetHeight;
						},500);
					};

					bindMsgList();
					window.addEventListener('resize', function() {
						ui.areaMsgList.scrollTop = ui.areaMsgList.scrollHeight + ui.areaMsgList.offsetHeight;
					}, false);
					var send = function(msg) {
						record.push(msg);
						bindMsgList();
					};
					var toRobot = function(info) {
						bindMsgList();
					};

					function msgTextFocus() {
							ui.boxMsgText.focus();
							setTimeout(function() {
								ui.boxMsgText.focus();
							}, 150);
						}
						//解决长按“发送”按钮,导致键盘关闭的问题;
					ui.footerRight.addEventListener('touchstart', function(event) {

						if (ui.btnMsgType.classList.contains('mui-icon-paperplane')) {
							msgTextFocus();
							event.preventDefault();
						}
					});
					//解决长按“发送”按钮,导致键盘关闭的问题;
					ui.footerRight.addEventListener('touchmove', function(event) {
						if (ui.btnMsgType.classList.contains('mui-icon-paperplane')) {
							msgTextFocus();
							event.preventDefault();
						}
					});
					ui.footerRight.addEventListener('release', function(event) {
						//
						if(ui.boxMsgText.value.length<1){
							//mui.toast("近期开放");
							return;
						}

						if (ui.btnMsgType.classList.contains('mui-icon-paperplane')) {
							//showKeyboard();
							ui.boxMsgText.focus();
							setTimeout(function() {
								ui.boxMsgText.focus();
							}, 150);
							//							event.detail.gesture.preventDefault();

							//接收服务器端显示,取代本地显示
							/*send({
								sender: 'self',
								type: 'text',
								content: ui.boxMsgText.value.replace(new RegExp('\n', 'gm'), '<br/>')
							});*/
							var content=ui.boxMsgText.value.replace(new RegExp('\n', 'gm'), '<br/>');
							ui.boxMsgText.value = '';
							$.trigger(ui.boxMsgText, 'input', null);

							//console.log(plus.webview.currentWebview().account+"ee");
							//同步内容
							CHAT.submit(content,plus.webview.currentWebview().account);//接收者

						} else if (ui.btnMsgType.classList.contains('icon-yuyin')) {
							ui.btnMsgType.classList.add('icon-xiepinglun');
							ui.btnMsgType.classList.remove('icon-yuyin');
							ui.boxMsgText.style.display = 'none';
							ui.boxMsgSound.style.display = 'block';
							ui.boxMsgText.blur();
							document.body.focus();
						} else if (ui.btnMsgType.classList.contains('icon-xiepinglun')) {
							ui.btnMsgType.classList.add('icon-yuyin');
							ui.btnMsgType.classList.remove('icon-xiepinglun');
							ui.boxMsgSound.style.display = 'none';
							ui.boxMsgText.style.display = 'block';
							//--
							//showKeyboard();
							ui.boxMsgText.focus();
							setTimeout(function() {
								ui.boxMsgText.focus();
							}, 150);
						}
					}, false);
					ui.footerLeft.addEventListener('tap', function(event) {
						if(onlineUsers2.hasOwnProperty(code)){
							var btnArray = [{
								title: "拍照"
							}, {
								title: "从相册选择"
							}];
							plus.nativeUI.actionSheet({
								title: "选择照片",
								cancel: "取消",
								buttons: btnArray
							}, function(e) {
								var index = e.index;
								switch (index) {
									case 0:
										break;
									case 1:
										var cmr = plus.camera.getCamera();
										cmr.captureImage(function(path) {
											var dstname = "_downloads/" + getUid() + ".jpg";
											compressImage(path, dstname);
											plus.nativeUI.showWaiting( "正在压缩图片" );
											getNewUrl();
	//										send({
	//											sender: 'self',
	//											type: 'image',
	//											content: "file://" + plus.io.convertLocalFileSystemURL(path)
	//										});
										}, function(err) {});
										break;
									case 2:
										plus.gallery.pick(function(path) {
											var dstname = "_downloads/" + getUid() + ".jpg";
											compressImage(path, dstname);
											plus.nativeUI.showWaiting( "正在压缩图片" );
											getNewUrl();
	//
										}, function(err) {

										}, {
											filter: "image"
										});
										break;
								}
							});
						}
						else{
							mui.toast("对方不在线");
						}

					}, false);
					var files = [];
					var newUrlAfterCompress;
					function getNewUrl(){
						if(newUrlAfterCompress!=undefined){
							//console.log("转换后图片:"+newUrlAfterCompress);
							appendFile(newUrlAfterCompress);
							plus.nativeUI.showWaiting( "正在上传图片" );
							upload();
						}
						else{
							setTimeout(getNewUrl,300);
						}
					}
					// 上传文件
					function upload() {
						//var wt = plus.nativeUI.showWaiting();
						var task = plus.uploader.createUpload(server + "?action=testupload", {
								method: "POST"
							},
							function(t, status) { //上传完成
								if (status == 200) {
									//mui.toast("图片上传成功");
									var imgurl=t.responseText;
									var userimg=plus.storage.getItem("userimg");
									if(userimg.length>3){

									}
									else{
										userimg="img/logo.png";
									}
//									console.log(imgurl);
									var obj = {
						                send: plus.storage.getItem("loginname"),//this.userid,
						                username: plus.storage.getItem("loginname"),//this.username,
						                content: imgurl,
						                contentType:'image',
						                receive:code,
						                groupid:'0',
						                uname:plus.storage.getItem("realname"),
						                upic:userimg,
						                type:'self'
						            };
						            //plus.webview.currentWebview().groupid
						            files = [];
						            newUrlAfterCompress=undefined;
						            this.socket = io.connect('ws://121.40.205.128:3000');
						            this.socket.emit('message', obj);

						            plus.nativeUI.closeWaiting();
									//wt.close();
								} else {
									console.log("上传失败:" + status);

								}
							}
						);
						for (var i = 0; i < files.length; i++) {
							var f = files[i];
//							console.log("准备上传的图片路径:"+f.path);
							task.addFile(f.path, {
								key: f.name
							});
						}
						task.start();
					}
					function appendFile(p) {
						files.push({
							name: "uploadkey",//服务端接收<span style="font-family: Arial, Helvetica, sans-serif;">uploadkey,再转存为图片就行了</span>
							path: p
						});
					}
					// 产生一个随机数
					function getUid() {
						return Math.floor(Math.random() * 100000000 + 10000000).toString();
					}
					//压缩图片
					function compressImage(src, dstname) {
						//var dstname="_downloads/"+getUid()+".jpg";
						plus.zip.compressImage({
								src: src,
								dst: dstname,
								overwrite: true,
								quality: 20//图片压缩
							},
							function(event) {
								//console.log("Compress success:"+event.target);
								newUrlAfterCompress=event.target;
								return event.target;
							},
							function(error) {
								console.log(error);
								return src;
								//alert("Compress error!");
							});
					}
					var setSoundAlertVisable=function(show){
						if(show){
							ui.boxSoundAlert.style.display = 'block';
							ui.boxSoundAlert.style.opacity = 1;
						}else{
							ui.boxSoundAlert.style.opacity = 0;
							//fadeOut 完成再真正隐藏
							setTimeout(function(){
								ui.boxSoundAlert.style.display = 'none';
							},200);
						}
					};
					var recordCancel = false;
					var recorder = null;
					var audio_tips = document.getElementById("audio_tips");
					var startTimestamp = null;
					var stopTimestamp = null;
					var stopTimer = null;
					ui.boxMsgSound.addEventListener('hold', function(event) {
						recordCancel = false;
						if(stopTimer)clearTimeout(stopTimer);
						audio_tips.innerHTML = "手指上划,取消发送";
						ui.boxSoundAlert.classList.remove('rprogress-sigh');
						setSoundAlertVisable(true);
						recorder = plus.audio.getRecorder();
						if (recorder == null) {
							plus.nativeUI.toast("不能获取录音对象");
							return;
						}
						startTimestamp = (new Date()).getTime();
						recorder.record({
							filename: "_doc/audio/"
						}, function(path) {
							if (recordCancel) return;
							send({
								sender: 'self',
								type: 'sound',
								content: path
							});
						}, function(e) {
							plus.nativeUI.toast("录音时出现异常: " + e.message);
						});
					}, false);
					ui.body.addEventListener('drag', function(event) {
						//console.log('drag');
						if (Math.abs(event.detail.deltaY) > 50) {
							if (!recordCancel) {
								recordCancel = true;
								if (!audio_tips.classList.contains("cancel")) {
									audio_tips.classList.add("cancel");
								}
								audio_tips.innerHTML = "松开手指,取消发送";
							}
						} else {
							if (recordCancel) {
								recordCancel = false;
								if (audio_tips.classList.contains("cancel")) {
									audio_tips.classList.remove("cancel");
								}
								audio_tips.innerHTML = "手指上划,取消发送";
							}
						}
					}, false);
					ui.boxMsgSound.addEventListener('release', function(event) {
						//console.log('release');
						if (audio_tips.classList.contains("cancel")) {
							audio_tips.classList.remove("cancel");
							audio_tips.innerHTML = "手指上划,取消发送";
						}
						//
						stopTimestamp = (new Date()).getTime();
						if (stopTimestamp - startTimestamp < MIN_SOUND_TIME) {
							audio_tips.innerHTML = "录音时间太短";
							ui.boxSoundAlert.classList.add('rprogress-sigh');
							recordCancel = true;
							stopTimer=setTimeout(function(){
								setSoundAlertVisable(false);
							},800);
						}else{
							setSoundAlertVisable(false);
						}
						recorder.stop();
					}, false);
					ui.boxMsgSound.addEventListener("touchstart", function(e) {
						//console.log("start....");
						e.preventDefault();
					});
					ui.boxMsgText.addEventListener('input', function(event) {
						ui.btnMsgType.classList['add']('mui-icon-paperplane');
						ui.btnMsgType.setAttribute("for", ui.boxMsgText.value == '' ? '' : 'msg-text');
						ui.h.innerText = ui.boxMsgText.value.replace(new RegExp('\n', 'gm'), '\n-') || '-';
						ui.footer.style.height = (ui.h.offsetHeight + footerPadding) + 'px';
						ui.content.style.paddingBottom = ui.footer.style.height;
					});
					ui.boxMsgText.addEventListener('tap', function(event) {
						ui.boxMsgText.focus();
						setTimeout(function() {
							ui.boxMsgText.focus();
						}, 0);
					}, false);
				var conn=new DBConn();
				//保存联系人表
				function insertData(send,receive,content,uname){
					var sql="select * from chart_list where send='"+send+"' and receive='"+receive+"'";
					console.log("监听最近联系人"+sql);
					conn.executeScarl(sql,
						function(tx,result){
							console.log("sql的结果集"+result.rows.length);
							if(result.rows.length>0){
								//存在最近记录
								sql="update chart_list set content='"+content+"' where send='"+send+"' and receive='"+receive+"'";
								conn.executeSqlDefault(sql,
									[],
									function (tx, result) {
										//保存成功
									},
									function (tx, error) {
										console.log('记录保存失败: ' + error.message);

									}
								);
							}else{
								conn.executeScarl("select * from chart_list order by id desc limit 0,1",
									function(tx,result){
										/*var id=0;
										if(result.rows.length>0){
											id=parseInt(result.rows.item(0)["id"])+1;
										}else{
											id=1;
										}*/
										//添加最近记录,判断是否存在记录,无责为1,否则为最大值+1
										var da=new Date();
										var adddate=da.getFullYear()+"-"+(da.getMonth()+1)+"-"+da.getDay()+" "+da.getHours()+":"+da.getMinutes()+":"+da.getSeconds();
										sql="insert into chart_list (send,receive,addtime,content,groupid,uname) values('"+send+"','"+receive+"','"+adddate+"','"+content+"',0,'"+uname+"')";
										//console.log(sql);
										conn.executeSqlDefault(sql,
											[],
											function (tx, result) {
												//保存成功
											},
											function (tx, error) {
												console.log('记录保存失败: ' + error.message);
											}
										);
									}
								)
							}
						},function(tx,error){
							console.log(error);
						}
					);
				}
				//保存聊天内容表
				function insertDataContent(id,send,receive,adddate,content,contentType,type,upic){
					conn.executeScarl("select * from chart_list_content order by addtime desc limit 0,1",
						function(tx,result){
							var type="";
							if(plus.storage.getItem("loginname")==send){
								type='self';
							}else{
								type='send';
							}
							//添加最近记录,判断是否存在记录,无责为1,否则为最大值+1
							var sql="insert into chart_list_content (id,send,receive,addtime,content,contentType,type,isread,upic) values('"+id+"','"+send+"','"+receive+"','"+adddate+"','"+content+"','"+contentType+"','"+type+"',1,'"+upic+"')";
//							console.log(sql);
							//console.log(sql+"ee");
							conn.executeSqlDefault(sql,
								[],
								function (tx, result) {
									//保存成功
									record.push({
										sender: type,
										type: contentType,
										content: content,
										addtime:adddate,
										upic:upic
									});
									bindMsgList();
								},
								function (tx, error) {
									console.log('记录保存失败: ' + error.message);
								}
							);
						}
					)
				}
				//群组--------------------------
				//保存联系人表
				function insertGroupData(send,receive,content,groupid,gname,pic){
					var sql="";
					conn.executeScarl("select * from chart_list where groupid='"+groupid+"'",
						function(tx,result){
							if(result.rows.length>0){
								//存在最近记录
								sql="update chart_list set content='"+content+"' where groupid='"+groupid+"'";
								conn.executeSqlDefault(sql,
									[],
									function (tx, result) {
										//保存成功
									},
									function (tx, error) {
										console.log('记录保存失败: ' + error.message);
									}
								);
							}else{
								conn.executeScarl("select * from chart_list order by addtime desc limit 0,1",
									function(tx,result){
										/*var id=0;
										if(result.rows.length>0){
											id=parseInt(result.rows.item(0)["id"])+1;
										}else{
											id=1;
										}*/
										//添加最近记录,判断是否存在记录,无责为1,否则为最大值+1
										var da=new Date();
										var adddate=da.getFullYear()+"-"+(da.getMonth()+1)+"-"+da.getDay()+" "+da.getHours()+":"+da.getMinutes()+":"+da.getSeconds();
										sql="insert into chart_list (send,receive,addtime,content,groupid,uname,gname,pic) values('','','"+adddate+"','"+content+"','"+groupid+"','','"+gname+"','"+pic+"')";
//										console.log(sql);
										conn.executeSqlDefault(sql,
											[],
											function (tx, result) {
												//保存成功
											},
											function (tx, error) {
												console.log('记录保存失败: ' + error.message);
											}
										);
									}
								)
							}
						}
					);
				}
				//保存群组聊天内容表
				function insertDataGroupContent(id,send,receive,adddate,content,contentType,type,groupid){
					conn.executeScarl("select * from chart_group_list_content order by addtime desc limit 0,1",
						function(tx,result){
							var type="";
							if(plus.storage.getItem("loginname")==send){
								type='self';
							}else{
								type='send';
							}
							//添加最近记录,判断是否存在记录,无责为1,否则为最大值+1
							var sql="insert into chart_group_list_content (id,send,content,contentType,addtime,type,groupid) values('"+id+"','"+send+"','"+content+"','"+contentType+"','"+adddate+"','"+type+"',"+groupid+")";
							//console.log(sql);
							conn.executeSqlDefault(sql,
								[],
								function (tx, result) {
									//保存成功
									//initList();
								},
								function (tx, error) {
									console.log('记录保存失败: ' + error.message);
								}
							);
						}
					)
				}

				//显示本地聊天信息
				function initData(){
					//conn.executeScarl("select * from chart_list_content where (send='"+plus.webview.currentWebview().account+"' or send='"+plus.storage.getItem("loginname")+"') and (receive='"+plus.storage.getItem("loginname")+"' or receive='"+plus.webview.currentWebview().account+"')  order by id asc limit 0,100",
					conn.executeScarl("select * from chart_list_content where (send='"+plus.webview.currentWebview().account+"' and receive='"+plus.storage.getItem("loginname")+"') or (send='"+plus.storage.getItem("loginname")+"' and receive='"+plus.webview.currentWebview().account+"')  order by id asc limit 0,100",
					function(tx,result){
						if(result.rows.length>0){
							for(var i=0;i<result.rows.length;i++){
								record.push({
									sender: result.rows.item(i)["type"],
									type: result.rows.item(i)["contentType"],
									content: result.rows.item(i)["content"],
									addtime:result.rows.item(i)["addtime"],
									groupid:0,
									upic:result.rows.item(i)["upic"]
								});
								bindMsgList();
							}
						}
					});
				};
				initData();

				var d = document,
				w = window,
				p = parseInt,
				dd = d.documentElement,
				db = d.body,
				dc = d.compatMode == 'CSS1Compat',
				dx = dc ? dd: db,
				ec = encodeURIComponent;

				w.CHAT = {
				    msgObj:d.getElementById("message"),
				    screenheight:w.innerHeight ? w.innerHeight : dx.clientHeight,
				    username:null,
				    userid:null,
				    socket:null,
				    onlineUsers:null,
				    reivice:null,
				    //让浏览器滚动条保持在最低部
				    scrollToBottom:function(){
				        //w.scrollTo(0, this.msgObj.clientHeight);
				    },
				    //退出,本例只是一个简单的刷新
				    logout:function(){
				        //this.socket.disconnect();
				        //location.reload();
				    },
				    //提交聊天消息内容
				    submit:function(content,reivicer){
				        var content = content;
				        if(content != ''){
				        	var arrUserList;
//				        	var arrUserList=onlineUsers.split('、');
							if(onlineUsers2.hasOwnProperty(reivicer)){
				                var userimg=plus.storage.getItem("userimg");

					        	if(userimg.length<1){
					        		userimg="img/logo.png";
					        	}
					            var obj = {
					                send: plus.storage.getItem("loginname"),//this.userid,
					                username: plus.storage.getItem("loginname"),//this.username,
					                content: content,
					                contentType:'text',
					                receive:reivicer,
					                groupid:0,
					                type:'self',
					                uname:plus.storage.getItem("realname"),
					                upic:userimg
					            };
					            this.socket = io.connect('ws://121.40.205.128:3000');
					            this.socket.emit('message', obj);
				            }
				            else{
				            	mui.toast("对方不在线");
				            	return false;
				            }
//				        	console.log(arrUserList);

				        }

				        return false;
				    },
				    genUid:function(){
				        return new Date().getTime()+""+Math.floor(Math.random()*899+100);
				    },
				    //更新系统消息,本例中在用户加入、退出的时候调用
				    updateSysMsg:function(o, action){
				        //当前在线用户列表
				        onlineUsers2 = o.onlineUsers;
				        //当前在线人数
				        var onlineCount = o.onlineCount;
				        //新加入用户的信息
				        var user = o.user; 

				        //更新在线人数
				        var userhtml = '';
				        var separator = '';
//				        for(key in onlineUsers) {
//				            if(onlineUsers2.hasOwnProperty(key)){
//				                userhtml += separator+onlineUsers[key];
//				                separator = '、';
//				            }
//				        }
				    },
				    //第一个界面用户提交用户名
				    usernameSubmit:function(){
				        return false;
				    },
				    init:function(){
				        /*
				        客户端根据时间和随机数生成uid,这样使得聊天室用户名称可以重复。
				        实际项目中,如果是需要用户登录,那么直接采用用户的uid来做标识就可以
				        */
				        this.userid = plus.storage.getItem("loginname");
				        this.username = plus.storage.getItem("loginname"); 

				        //连接websocket后端服务器
				        this.socket = io.connect('ws://121.40.205.128:3000');

				        //告诉服务器端有用户登录
				        this.socket.emit('login', {userid:this.userid, username:this.username}); 

				        //监听新用户登录
				        this.socket.on('login', function(o){
				            CHAT.updateSysMsg(o, 'login');
				        }); 

				        //监听用户退出
				        this.socket.on('logout', function(o){
				            CHAT.updateSysMsg(o, 'logout');
				        });
				        //监听消息发送
				        this.socket.on('message', function(obj){
				        	//监听服务器发送的消息,保存到本地,然后展示
//				        	console.log("监听时收到的obj.groupid"+obj.groupid);
				        	if(obj.groupid==0){
					        	conn.executeScarl("select * from chart_list_content where id='"+obj.id+"'",
								function(tx,result){
					        		//单人聊天监听保存
					        		conn.executeScarl("select * from chart_list_content where id='"+obj.id+"'",
									function(tx,result){
										if(result.rows.length==0){
											var send="";
											if(obj.send==plus.storage.getItem("loginname")){
												send=obj.receive;
											}else{
												send=obj.send;
											}
											//insertData(send,receive,content,uname)
											insertData(send,plus.storage.getItem("loginname"),obj.content,obj.uname);
						        			insertDataContent(obj.id,obj.send,obj.receive,obj.addtime,obj.content,obj.contentType,obj.type,obj.upic);
										}
									});

								});
							}else{
				        		//群组聊天监听保存
				        		conn.executeScarl("select * from chart_group_list_content where id='"+obj.id+"'",
								function(tx,result){
									if(result.rows.length==0){
										var send="";
										if(obj.send==plus.storage.getItem("loginname")){
											send=obj.receive;
										}else{
											send=obj.send;
										}
										if(localStorage.chartitem!="show"){

										}else{
											//initList();
											//insertGroupData(send,receive,content,groupid,gname,pic){
											insertGroupData(send,plus.storage.getItem("loginname"),obj.content,obj.groupid,"",plus.storage.getItem("userimg"));
				        					insertDataGroupContent(obj.id,obj.send,obj.receive,obj.addtime,obj.content,obj.contentType,obj.type,1);
										}
									}
								});
				        	}
			            });
			            this.socket.on('notline', function(obj){
			            	mui.toast("对方不在线");
			            });
			        }
			    };
				CHAT.init();
			});
			}(mui, document));
		</script>
	</body>
</html>

服务端接收图片,并返回网络路径:

int l = Request.Files["uploadkey"].ContentLength;
byte[] buffer = new byte[l];
Stream s = Request.Files["uploadkey"].InputStream;
//string imgtype = Request.Files[3 + i].ContentType;
//image/png
System.Drawing.Bitmap image = new System.Drawing.Bitmap(s);
string imgname = Common.GetGuid() + ".jpg";
string path = "Images/" + DateTime.Now.ToString("yyyyMMdd");
if (!Directory.Exists(HttpContext.Current.Server.MapPath(path)))
{
    System.IO.Directory.CreateDirectory(HttpContext.Current.Server.MapPath(path));
}
string newurl=Server.MapPath(path + "/" + imgname);
image.Save(newurl);
时间: 2024-08-01 18:23:58

H5+MUI+Node.js+Socket.io实现即时聊天以及发送+图片压缩的相关文章

H5+MUI+Node.js+Socket.io群组即时聊天+发送图片+图片压缩

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title></title

Node.js+socket.io在线聊天室

Node.js+socket.io实现在线聊天室,照着这个教程做的,稍加改动即可实现. Node.js:0.10.31 Express:3.* 创建工程chat: 添加几个文件,工程结构如下 代码: package.json: { "name": "application-name", "version": "0.0.1", "private": true, "scripts": { &

使用Node.js+Socket.IO搭建WebSocket实时应用【转载】

原文:http://www.jianshu.com/p/d9b1273a93fd Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. WebSocket简介 谈到Web实时推送,就不得不说WebSocket.在WebSocket出现之前,很多网站为了实现实时推送技术,通常采用的方案是轮询(Polling)和Comet技术,Comet又可细分为两种实现方

[转载]使用node.js+socket.io搭建实时消息系统

在开发web应用时,经常会有消息接收需求.例如后台处理完某个任务,需要告知用户等.一个简单的做法,是使用ajax轮询.这样带来的问题一是低效,二是消息触达不够实时.另一个方法是使用websocket来接收消息,但可惜IE不支持这种方式.下面推荐一种既能实时接收消息,又能兼容各种浏览器的方案,那就是node.js+socket.io. node.js的异步非阻塞模型,做消息推送非常合适.socket.io则负责屏蔽浏览器的差异,其会选择性的使用下列方式建立连接:websocket, flash s

使用Node.js+Socket.IO搭建WebSocket实时应用

Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. 作者:潘良虎链接:https://www.zhihu.com/question/20215561/answer/26419995来源:知乎原文地址:http://www.plhwin.com/2014/05/28/nodejs-socketio/ WebSocket简介 谈到Web实时推送,就不得不说

(转)使用Node.js+Socket.IO搭建WebSocket实时应用

Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. WebSocket简介 谈到Web实时推送,就不得不说WebSocket.在WebSocket出现之前,很多网站为了实现实时推送技术,通常采用的方案是轮询(Polling)和Comet技术,Comet又可细分为两种实现方式,一种是长轮询机制,一种称为流技术,这两种方式实际上是对轮询技术的改进,这些方案

用node.js(socket.io)实现数据实时推送

在做商品拍卖的时候,要求在商品的拍卖页面需要实时的更新当前商品的最高价格.实现的方式有很多,比如: 1.setInterval每隔n秒去异步拉取数据(缺点:更新不够实时) 2. AJAX轮询方式方式推送数据(缺点:服务端需要在死循环中反复查询数据库) 3.websocket推送数据(缺点:仅支持html5标准的浏览器) socket.io的简要介绍 所有客户端都通过socket.io挂在nodejs服务器上(注意: 只是挂着,不需要任何循环,因为它是事件驱动的):需要推送消息了,服务器就与nod

基于node.js+socket.io+html5实现的斗地主游戏(1)概述

一.游戏描述 说是斗地主游戏,其实是寝室自创的"捉双A",跟很多地方的捉红10.打红A差不多,大概规则是: 1.基础牌型和斗地主一样,但没有大小王,共52张牌,每人13张,这也是为什么题目直接叫斗地主游戏的原因了. 2.手牌有黑桃A和草花A的两个人一伙:若黑桃A和草花A都在一个人手里,那就自己一伙. 3.开牌之后可以选择亮A或者不亮A,亮A之后队友也应亮明身份,互相配合出牌. 4.随机指定最先出牌者. 5.按照手牌出完顺序记分数,分别记4.3.2.1分,最后整队加和,分数高的队伍获胜.

Node.js+websocket+mongodb实现即时聊天室

ChatRoom Node.js+websocket+mongodb实现即时聊天室 A,nodejs简介:Node.js是一个可以让javascript运行在服务器端的平台,它可以让javascript脱离浏览器的束缚运行在一般的服务器下面,你可以用Node.js轻松地进行服务器端应用的开发.Node.js是一个为实时Web应用开发而诞生的平台,它充分考虑了在实时响应和超大规模数据下架构的可扩展性,这使得它摒弃了传统的平台依靠多线程来实现高并发的的设计思路,而采用了单线程,异步式I/O和事件驱动