有时候自我感觉良好,人啊就开始膨胀,细细想来,自己还是那么苍白。---- 致傻傻的我
大家都知道,平时上班总是拿着手机看看微信,看看新闻,这个不太好,这不是重点,重点是我们公司web版本的微信,QQ都上不去,这也不是重点,若我还是单身。现在有媳妇指令的时候,总是接收不到,这个不太好。
于是就想自己写一个聊天的好了,是男人说干就干呗。
功能需求
1. 文本消息
2. 消息提示,因为是web版本,如果不在当前窗前窗口的时候,需要智能提示,如果在,当然不需要
3. 一些内置的动态表情
4. 图片的传送,
图片粘贴,
图片拖拽
5. 文件的拖拽
6. 一对多的 图片和文件传送
7. 支持多人聊天即多窗口聊天
8. 语音 + 视频聊天
实现思路
1. 语言
我数数我会的语言也就是C#,nodejs, java,勉强能读php,
其实一直想用php写点啥来着,我看好php的p(飘逸),但是不是现在,
java 不喜欢笨重的大叔,一直都很讨厌,最不喜欢的语言,没有之一,
C#,原来的老本行,虽然用了那么久,一直基于产品的二次开发,想想自己真是个弱鸡,原来用 C#作为后台写了个pm25实时引用和在线的五子棋,可行,但是不想用了,
2016年3月转了专门的js,至少我喜欢,就是你了- nodejs
2. socket.io
其实选择了nodejs,你也没得选了
3. 消息提示
Notification
4. 视频聊天
webrtc(adapter.js)
基本上就这些了,实现的程度,也是按照需求的顺序
虽说是连续剧,这一集,必须有点料,那就是基本的文本聊天。
nodejs + socket.io + html5 web socket 这种聊天,太多了。我就不解释了,也不多说了。
消息提示的逻辑依然是 如果不在当前窗口的时候,需要智能提示,如果在,当然不需要
那么问题的重点就是,
1. 如何判断当前窗框是不是不激活,反过来是不是被隐藏了,查看代码方法 getWindowHiddenKey,获得判断当前穿孔是不是hidden的属性名,然后document[propertyName]就可以得知是不是隐藏了
2. 如果把消息通知给用户,这里就用到了window.Notification,他会在桌面右下角弹出一个框,显示必要的信息,图片,标题,消息正文,关闭按钮,设置按钮等
可以参考如下文章:
简单了解HTML5中的Web Notification桌面通知 « 张鑫旭-鑫空间-鑫生活
3. 如何让消息提示不消失,一直提示
为什么这么做了,女人嘛,有时候分神,一个不小心关闭了,咋办了。
本来是想通过设置完成的,结果查看了文档,没有找到合适的,等待高人指点哈。
好像有个windows的设置,但是觉得这个有点麻烦用户了。
我的思路是在关闭的时候再次打开提示框,以得以延续。
4. 如何回到页面聊天
这个问题,开始我也一直再想,官方文档上有答案,notification的click里面调用window.focus(),我差点怀疑自己是不是懂html和js.
好吧,废话不多了,上代码。
define(function (require, exports, module) { class Notify { constructor(alwaysShow = false) { this.supported = window.Notification != null this.options = { renotify: true, noscreen: false, tag: 'jchat', icon: '/img/notify_title.jpg' } this.hiddenKey = Notify.getWindowHiddenKey() this.alwaysShow = alwaysShow || false this.manualClosed = false } popNotify(title, options) { let opt = Object.assign({}, this.options, options) if (Notification.permission == 'granted') { var notification = new Notification(title, opt) this.initalizeNotification(notification, title, opt) } } initalizeNotification(notification, title, options) { notification.onclick = () => { //返回消息窗口 //关闭消息框 this.manualClosed = true notification.close() window.focus() } notification.onclose = () => { if (document[this.hiddenKey] && this.alwaysShow && !this.manualClosed) { this.manualClosed = false notification = new Notification(title, options) this.initalizeNotification(notification, title, options) }else{ this.manualClosed = false } } } pop(title, options) { //若是支持并且隐藏,弹出消息 if (this.supported && document[this.hiddenKey]) { if (Notification.permission == 'granted') { this.popNotify(title, options) } else if (Notification.permission != 'denied') { Notification.requestPermission(() => { this.popNotify(title, options) }) } } } static getWindowHiddenKey() { if (typeof document.hidden !== 'undefined') { this.hiddenKey = 'hidden' } else if (typeof document.mozHidden !== 'undefined') { this.hiddenKey = 'mozHidden' } else if (typeof document.msHidden !== 'undefined') { this.hiddenKey = 'msHidden' } else if (typeof document.webkitHidden !== 'undefined') { this.hiddenKey = 'webkitHidden' } return this.hiddenKey } } module.exports = Notify })
演示地址:https://babydairy2017.cloudapp.net:8081/chat.html