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

22 篇文章 0 订阅

<!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);

db.js源码:

/*管理本地sql相关脚本*/

var DBConn = function() {

	var dbName = 'abcde'; //数据库名
	var version = '2.0'; //版本信息
	var description = 'abcd'; //描述
	var maxSize = 5 * 1024 * 1024; //最大值
	var dbObj = null;

	//打开数据库
	function openDB() {
		try {
			if (!dbObj) {
				dbObj = openDatabase(dbName, version, description, maxSize);
			}
		} catch (e) {
			console.log("打开数据库出现未知错误: " + e);
			dbObj = null;
		}
		return dbObj;
	}

	this.getDBconn = function() {
		openDB();
		return dbObj;
	}

	this.executeSqlDefault = function(sqlStr, params, successHandler, errorHandler) {
		openDB();
		dbObj.transaction(function(tx) {
			tx.executeSql(sqlStr, params, successHandler, errorHandler);
		}, function(transaction, result) {}, function(tx, error) {});
	}

	this.executeSqlTrans = function(fun, successHandler, errorHandler) {
		openDB();
		dbObj.transaction(fun, errorHandler, successHandler);
	}

	//修改数据库版本信息
	this.changeDBVersion = function(oldVersion, newVersion) {
		dbObj = openDB();
		dbObj.changeVersion(oldVersion, newVersion, function(transaction, result) {}, function(tx, error) {});
	}

	//创建表
	this.createTable = function(tableName, sql) {
		dbObj = openDB();
		isExitTable(tableName,
			function() {
				//存在表,不执行
			},
			function() {
				//不存在,执行创建
				dbObj.transaction(function(tx) {
					tx.executeSql(sql, [], function(transaction, result) {
						console.log("表[" + tableName + "]创建失败");
					}, function(tx, error) {});
				});
			}
		);
	}

	//不判断直接执行创建表
	this.createTableNoCheck = function(tableName, sql) {
		dbObj = openDB();
		
		dbObj.transaction(function(tx) {
			tx.executeSql(sql, [], function(transaction, result) {
				//mui.toast("表["+tableName+"]创建失败"); 
			}, function(tx, error) {

			});
		});
	}

	//判断某表是否存在:表名、存在回调函数、不存在回调函数
	this.isExitTable = function(tableName, exitFun, noexitFun) {
		dbObj = openDB();
		var sql = "select * from sqlite_master where type='table' and name = ?";
		dbObj.transaction(function(tx) {
			tx.executeSql(sql, [tableName], function(transaction, result) {
				if (result.rows.length > 0 && exitFun) {
					exitFun.call();
				} else if (result.rows.length <= 0 && noexitFun) {
					noexitFun.call();
				}
			}, function(tx, error) {

			});
		});

	}

	//删除表数据:表名,删除成功回调函数
	this.delTbleData = function(tableName, callBackFun) {
		dbObj = openDB();
		var sql = "delete from ?";
		dbObj.transaction(function(tx) {
			tx.executeSql(sql, [tableName], callBackFun, function(tx, error) {});
		});
	}

	//删除表,删除成功回调函数
	this.delTbleData = function(tableName, callBackFun) {
		dbObj = openDB();
		var sql = "drop table ?";
		dbObj.transaction(function(tx) {
			tx.executeSql(sql, [tableName], callBackFun, function(tx, error) {});
		});
	}
	this.delTble = function(tableName, callBackFun,callErrFun) {
		dbObj = openDB();
		var sql = "drop table "+tableName;
		dbObj.transaction(function(tx) {
			tx.executeSql(sql, [], callBackFun, callErrFun);
		});
	}
	this.executeScarl = function(sql, callBackFun, callErrFun) {
		dbObj = openDB();
		dbObj.transaction(function(tx) {
			tx.executeSql(sql, [], callBackFun, callErrFun);
		});
	}

	//登录时初始化数据库表
	this.initTable = function() {
		var sql = "";
		//最近联系人表

		sql = "CREATE TABLE if not exists chart_list (id UNIQUE,send,receive,addtime,content,contentType,groupid,uname,gname,pic)";
		this.createTableNoCheck('chart_list', sql);
		//最近联系人聊天内容表
		sql = "CREATE TABLE if not exists chart_list_content (id UNIQUE,send,receive,addtime,content,contentType,type,isread,upic)";
		this.createTableNoCheck('chart_list_content', sql);
		//群组聊天纪录表

		sql = "CREATE TABLE if not exists chart_group_list_content (id UNIQUE,send,content,contentType,addtime,type,groupid,uname,upic)";
		this.createTableNoCheck('chart_group_list_content', sql);



		sql = "create table if not exists dynamic (id,userid,realname,userimg,title,contents,joindate)";
		this.createTableNoCheck('dynamic', sql);
		

		sql = "create table if not exists dynamic_zan (id,did,username,joindate)";
		this.createTableNoCheck('dynamic_zan', sql);
		
		sql = "create table if not exists dynamic_comment (id,did,username,comment,joindate)";
		this.createTableNoCheck('dynamic_comment', sql);

		plus.storage.setItem("isdb", "true");
	}
}

login.js源码

//一些全局变量
var server = "http://192.168.1.106:8003/System/Controls/appinterface.aspx";

(function($, window) {

	/**
	 * 后退
	 */
	$.back = function() {
		if (typeof $.options.beforeback === 'function') {
			if ($.options.beforeback() === false) {
				return;
			}
		}
		var assign = plus.webview.getWebviewById('assign.html');
		mui.fire(assign, 'refresh', {//触发页面自定义事件
			id: ''
		});
		
		var dynamic = plus.webview.getWebviewById('Dynamic_Child.html');
		mui.fire(dynamic, 'rebind', {//触发动态页面自定义事件
			id: ''
		});
		
		var person=plus.webview.getWebviewById("personal.html");
		mui.fire(person,'refresh',{});
		$.doAction('backs');
	};


})(mui, window);

function login() {
//	mui.toast("正在登录,请稍候...");
	$("#login").attr("disabled",true);
	var user = $("#account").val();
	//alert(user);
	if (user.trim() == "") {
		mui.toast("账号不能为空!");
		return;
	}
	var pwd = $("#password").val();
	if (pwd.trim() == "") {
		mui.toast("密码不能为空!");
		return;
	}
	var date = new Date().getMilliseconds();
	var newurl = "";
	var uuid=plus.device.uuid;
	newurl = server + "?action=loginin&username=" + user + "&password=" + pwd + "&date=" + date+"&uuid="+uuid;
//	console.log(newurl);
	$.getJSON(newurl, success);
};
var success = function(response) {
	//alert(response.success);
	var strresponse = JSON.stringify(response);

	if (response.success) {
		mui.toast("登录成功");
		plus.storage.setItem("policeid", response.policeid);//用户ID
		plus.storage.setItem("loginname", response.loginname);//警号
		plus.storage.setItem("community", response.community);//社区编号
		plus.storage.setItem("branchcode", response.branchcode);//部门编号
		plus.storage.setItem("realname", response.realname);//真实姓名
		plus.storage.setItem("uuid", response.uuid);//不解释
		plus.storage.setItem("branchname", response.branchname);//部门名称
		plus.storage.setItem("phone", response.phone);
		plus.storage.setItem("phoneshort", response.phoneshort);
		plus.storage.setItem("communityname", response.communityname);
		plus.storage.setItem("userimg", response.img);
		plus.storage.setItem("role", response.role);
		mui.openWindow({
			url: 'main.html',
			id: 'main',
			show: {
				autoShow: false
			}
		});
	} else {
		mui.toast(response.error); //自动消失的提示框
		$("#login").removeAttr("disabled");
	}
	
}

function savepic(){//预览时保存图片
	mui.toast('正在保存,请稍等');
//				console.log($(".mui-imageviewer-item").children().children().attr("src"));
	var picurl=$(".mui-imageviewer-item").children().children().attr("src");//需要自己去找到图片的路径
	var dtask = plus.downloader.createDownload(picurl, {}, function(d, status) {
		// 下载完成
		if (status == 200) {
			console.log("Download success: " + d.filename);
			plus.gallery.save(d.filename, function() {
				mui.toast('保存成功');
			}, function(error) {
				mui.toast('保存失败,请重试!');
				console.log(error.code+""+error.message);
			});
		} else {
			console.log("Download failed: " + status);
		}
	
	});
	dtask.start();
}

服务端用Node.js监听,核心代码如下:

/* var app = require('express')(); 
var http = require('http').Server(app); 
var io = require('socket.io')(http); 
  
app.get('/', function(req, res){ 
    res.send('<h1>Welcome Realtime Server</h1>'); 
}); 
  
http.listen(3000, function(){ 
    console.log('listening on *:3000'); 
}); */
var app = require('express')(); 
var http = require('http').Server(app); 
var io = require('socket.io')(http); 
// 加载File System读写模块  
var fs = require('fs'); 


  
app.get('/', function(req, res){ 
    res.send('<h1>聊天服务已启动</h1>'); 
}); 
 
//在线用户 
var onlineUsers = {}; 
//当前在线人数 
var onlineCount = 0; 
  
io.on('connection', function(socket){ 
    //console.log('一个用户连接'); 
	
	/* var nowDate = new Date();
	var result = nowDate.getFullYear()+"-"+((nowDate.getMonth()+1)<10?"0"+(nowDate.getMonth()+1):(nowDate.getMonth()+1))+"-"+(nowDate.getDate())+" "+ nowDate.getHours()+":"+nowDate.getMinutes()+":"+nowDate.getSeconds();

	console.log(result); */
	
	//var moment = require("moment");moment().format("YYYY-MM-DD HH:mm:ss") 

	
	
    //监听新用户加入 
    socket.on('login', function(obj){ 
		var dates=new Date().format("yyyy-MM-dd hh:mm:ss");
		var file = "c:\\nodeLog.txt"; 
		function writeFile(str){  
			
			// appendFile,如果文件不存在,会自动创建新文件  
			// 如果用writeFile,那么会删除旧文件,直接写新文件 
			//var datenow=moment().format("YYYY-MM-DD HH:mm:ss");
			fs.appendFile(file, "["+dates+"]----"+str+"\n\r", function(err){  
				if(err)  
					console.log("fail " + err);  
				else  
					console.log("写入文件ok:----"+str);  
			});  
		}
        //将新加入用户的唯一标识当作socket的名称,后面退出的时候会用到 
        socket.name = obj.userid; 
        writeFile("User Login:"+obj.userid);
        //检查在线列表,如果不在里面就加入 
        if(!onlineUsers.hasOwnProperty(obj.userid)) { 
            onlineUsers[obj.userid] = obj.username; 
            //在线人数+1 
            onlineCount++; 
        } 
        //writeFile("11111111111111111");
        //向所有客户端广播用户加入 
        io.emit('login', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj}); 
		//writeFile("22222222222222");
        //console.log(obj.username+'加入了群组'); 
		for(var i=0;i<onlineUsers.length;i++){
			console.log(onlineUsers[i]);
		}
		//writeFile("333333333333333333333333");
		var db = module.exports = exports = require('./mssqlhelper/lib/mssqlhelper');
		db.config({  
			 host: '127.0.0.1'    
			,port: 1433  
			,userName:  'sa'    
			,password:  '123456'    
			,database: 'database'
			,poolSize:10000000
		});
		
		//writeFile("select * from  t_chart_msg where receive='"+obj.userid+"' and isread=0 ");
		//处理登录用户,登录后,判断是否有未读消息,有的话,发送到刚登录的客户端
		console.log("user:"+obj.userid);
		
		function writeObj(obj){ 
		 var description = ""; 
		 for(var i in obj){ 
		  var property=obj[i]; 
		  description+=i+" = "+property+"\n"; 
		  //description+= writeObj(property);
		 } 
		 return  (description); 
		} 
		db.query(
			  "select * from  t_chart_msg where receive='"+obj.userid+"' and isread=0 "
			 ,{				 
			 }  
			 , function (res){
				 
				 writeFile(writeObj(res));
				 //writeFile((res.tables[0]));
				 //writeFile("rows:"+writeObj(res.tables[0].rows));
				 //writeFile("rows:"+writeObj(res.tables[0].rows.length));
				 
				 try{
						if(res.tables[0]!=undefined){
							var rowss = res.tables[0].rows;
							var i = 0,j=0;
							var datestart=new Date().getTime();
							var dateend=datestart;
							while (i < rowss.length) {
								//writeFile(rowss[i]["send"]);
								//writeFile(rowss[i].getValue('content'));
								//writeFile(rowss[i].getValue('addtime'));
								//writeFile(rowss[i].getValue('receive'));
								//console.log(rowss[i].getValue('id'),rowss[i].getValue('send'),rowss[i].getValue('receive'),rowss[i].getValue('addtime'),rowss[i].getValue('content'),rowss[i].getValue('contentType'));
								//writeFile(rowss[i].getValue('send')+","+rowss[i].getValue('receive')+","+rowss[i].getValue('addtime')+","+rowss[i].getValue('content')+","+rowss[i].getValue('contentType'));
								obj.id=rowss[i].getValue('id');
								obj.send=rowss[i].getValue('send');
								obj.receive=rowss[i].getValue('receive');
								obj.addtime=rowss[i].getValue('addtime');
								obj.content=rowss[i].getValue('content');
								obj.contentType=rowss[i].getValue('contentType');
								obj.uname=rowss[i].getValue('uname');
								obj.upic=rowss[i].getValue('upic');
								obj.groupid=0;
								obj.isOffLineMsg='true';
								io.emit('message', obj);
								i++;				
							}
							db.query(
							  "update t_chart_msg set isread=1 where receive='"+obj.userid+"' and isread=0"
							 ,{
								  // Param1: { type :  'NVarChar' , size: 7,value :  'myvalue'  }   
								  // ,Param2: { type :  'Int' ,value : 321 }   
							 }  
							 , function (res){
								}
							 );
							 console.log("update t_chart_msg set isread=1 where receive='"+obj.userid+"' and isread=0");
							
						}
					}
					catch(e){
						writeFile('database error:'+e);
					}		
				 //保存到数据库成功,发送到客户端
				/*if(err){
					writeFile('database error:'+writeObj(err.tables[0]));					
					//throw new Error('database error:'+res.err.msg);
					//throw err;
				}
				else{
					writeFile("666666666666666666");
					
				}*/
						
			}  
		);  
		//writeFile("77777777777777777");
    }); 
    
    //监听用户退出 
    socket.on('disconnect', function(){ 
        //将退出的用户从在线列表中删除 
        if(onlineUsers.hasOwnProperty(socket.name)) { 
            //退出用户的信息 
            var obj = {userid:socket.name, username:onlineUsers[socket.name]}; 
            
            //删除 
            delete onlineUsers[socket.name]; 
            //在线人数-1 
            onlineCount--; 
            
            //向所有客户端广播用户退出 
            io.emit('logout', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj}); 
            console.log(obj.username+'退出了群组'); 
        } 
    }); 
    
    //监听用户发布聊天内容 
    socket.on('message', function(obj){ 
        //向所有客户端广播发布的消息 
        // io.emit('message', obj); 
        // console.log("["+obj.username+"] 对 ["+obj.reviceid+']说:'+obj.content);
		
		var db = module.exports = exports = require('./mssqlhelper/lib/mssqlhelper');
		db.config({  
			 host: '127.0.0.1'    
			,port: 1433  
			,userName:  'sa'    
			,password:  '123456'    
			,database: 'database'
			,poolSize:10000000
		});
		
		//在线
		var isread=0;
		var dates=new Date().format("yyyy-MM-dd hh:mm:ss");
		var file = "c:\\nodeLog.txt"; 
		function writeFile(str){  
			
			// appendFile,如果文件不存在,会自动创建新文件  
			// 如果用writeFile,那么会删除旧文件,直接写新文件 
			//var datenow=moment().format("YYYY-MM-DD HH:mm:ss");
			fs.appendFile(file, dates+":"+str+"\n\r", function(err){  
				if(err)  
					console.log("fail " + err);  
				else  
					console.log("写入文件ok");  
			});  
		}
		
		//处理是单人消息还是群组信息
		if(obj.groupid==0){
			//单人消息
			db.query(
			  "insert into t_chart_msg(send,receive,addtime,content,contentType,uname,isread,upic)values('"+obj.username+"','"+obj.receive+"','"+dates+"','"+obj.content+"','"+obj.contentType+"','"+obj.uname+"',"+isread+",'"+obj.upic+"') select cast(@@identity as varchar(10)) as id"
				 ,{  
				 }  
				 , function (res){
					 if(res.tables[0].rows!=undefined){
							var rowss = res.tables[0].rows;
							var id=rowss[0].getValue(0);
							obj.id=id;
							obj.addtime=dates;
							obj.contentType=obj.contentType;
							//保存到数据库成功,发送到客户端
							io.emit('message', obj);
							console.log("["+obj.username+"] 对 ["+obj.receive+']说:'+obj.content);
							writeFile("["+obj.username+"] 对 ["+obj.receive+']说:'+obj.content);
					 }
				}
			);
		}else{
			//群组消息
			db.query(
			  "insert into t_chart_msg_group(send,content,contentType,addtime,groupid,uname,upic)values('"+obj.send+"','"+obj.content+"','"+obj.contentType+"','"+dates+"','"+obj.groupid+"','"+obj.uname+"','"+obj.upic+"') select cast(@@identity as varchar(10)) as id"
				 ,{  
				 }  
				 , function (res){
					 if(res.tables[0].rows!=undefined){
							var rowss = res.tables[0].rows;
							var id=rowss[0].getValue(0);
							obj.id=id;
							obj.addtime=dates;
							obj.groupid=obj.groupid;
							obj.contentType=obj.contentType;
							obj.gname=obj.gname;
							obj.gpic=obj.gpic;
							//保存到数据库成功,发送到客户端
							io.emit('message', obj);
							writeFile("群组"+obj.groupid+"消息:["+obj.username+"] 对 ["+obj.groupid+obj.gname+']说:'+obj.content+",groupImg:"+obj.gpic);
							//console.log("群组"+obj.groupid+"消息:["+obj.username+"] 对 ["+obj.groupid+obj.gname+']说:'+obj.content);
					 }
				}
			);
		}
		
    }); 
}); 
  Date.prototype.format = function (format) {
            var o = {
                "M+": this.getMonth() + 1, //month 
                "d+": this.getDate(), //day 
                "h+": this.getHours(), //hour 
                "m+": this.getMinutes(), //minute 
                "s+": this.getSeconds(), //second 
                "q+": Math.floor((this.getMonth() + 3) / 3), //quarter 
                "S": this.getMilliseconds() //millisecond 
            }

            if (/(y+)/.test(format)) {
                format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
            }

            for (var k in o) {
                if (new RegExp("(" + k + ")").test(format)) {
                    format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
                }
            }
            return format;
        }
http.listen(3000, function(){ 
    console.log('listening on *:3000'); 
	//console.log('aaaaaaaaaaaaaaaaa');
}); 





其他就是相关的服务器配置文件了,剩余的,请自行百度。








  • 11
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
WebApp mui&H5+ 可以结合使用 Native.js for Android 完成视频录制和处理。以下是大致的实现步骤: 1. 引入 Native.js for Android 插件,该插件可以在 H5+ 中使用 Native 方法。 2. 使用 H5+ API 调用 Android 摄像头,获取视频流,并且使用 Native 方法将视频流传递给 Android Native 代码。 3. 在 Android Native 代码中,使用 Camera2 API 获得视频流,并且使用 MediaRecorder API 将视频流录制为 MP4 格式的视频。 4. 将录制好的视频文件保存到指定的路径,并且使用 Native 方法将视频文件路径传递给 H5+ 代码。 5. 在 H5+ 代码中,使用 HTML5 Video 标签来播放录制好的视频。 示例代码如下: H5+ 代码: ``` // 引入 Native.js for Android 插件 document.addEventListener('plusready', function() { var nativeApi = plus.android.importClass('io.dcloud.NativeApi'); var nativeObj = new nativeApi(); // 使用 H5+ API 调用 Android 摄像头 var cmr = plus.camera.getCamera(); cmr.startVideoCapture(function(path) { // 使用 Native 方法将视频流传递给 Android Native 代码 nativeObj.exec('com.example.camera', 'startRecording', [path], function(result) { console.log(result); // 使用 Native 方法将视频文件路径传递给 H5+ 代码 nativeObj.exec('com.example.camera', 'getVideoPath', [], function(path) { console.log(path); var video = document.getElementById('video'); video.src = path; video.play(); }, function(e) { console.log(e); }); }, function(e) { console.log(e); }); }, function(e) { console.log(e); }, {filename:'_doc/video/', index:1}); }); ``` Android Native 代码: ``` public class CameraPlugin extends CordovaPlugin { private CameraDevice cameraDevice; private MediaRecorder mediaRecorder; private String videoFilePath; @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if ("startRecording".equals(action)) { startRecording(args.getString(0), callbackContext); return true; } else if ("getVideoPath".equals(action)) { getVideoPath(callbackContext); return true; } return false; } private void startRecording(String path, CallbackContext callbackContext) { try { mediaRecorder = new MediaRecorder(); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mediaRecorder.setOutputFile(path); mediaRecorder.setVideoEncodingBitRate(10000000); mediaRecorder.setVideoFrameRate(30); mediaRecorder.setVideoSize(1280, 720); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mediaRecorder.prepare(); mediaRecorder.start(); videoFilePath = path; callbackContext.success(); } catch (Exception e) { callbackContext.error(e.getMessage()); } } private void getVideoPath(CallbackContext callbackContext) { callbackContext.success(videoFilePath); } // ... } ``` 需要注意的是,在 Android 6.0 及以上版本的系统中,需要动态请求摄像头和存储权限。同时,在录制视频时,需要使用新版的 Camera2 API 替换旧版的 Camera API。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值