先看软件成品:
客户端程序:
服务端程序:
开发初衷
跟女友有时候要异地,偶尔想在各自的电脑上打着视频电话看电影。看的途中可能某一方突然有事要暂停,那么正常来说要先在视频电话中跟对方讲然后各自在自己的电脑上按暂停键,事情忙完了又要跟对方讲然后各自按下播放键继续播放。有时可能进度不一样,要问对方你播放到哪啦?我调一下进度。基于这点,我觉得比较麻烦,而且现实中比较需要能解决这个问题的软件,所以就自己开发了。
说明
1.存储数据时并没有用到数据库,而是通过简单的写文件的方式。因为自己在阿里云租的数据库刚好过期了,而且前几天是情人节,想写完这个软件给女友一个惊喜,时间问题,就不想再弄数据库了。这个软件是在情人节前两天开始写,个人比较菜,写的过程中遇到很多问题,也让我成长了好多,感谢此次经历。
2.服务器程序是在腾讯云的服务器上,是windows系统,那个服务器用来个人学习练习专用,性能很低
再说一下软件功能
注册自己的帐号,然后登录。登录后在功能菜单中点击创建房间,设置房间密码后点击创建,然后叫朋友也注册,登录,然后把房间密码告诉朋友,朋友就可以加入房间中。
房间中的人选择好同一份本地的视频文件,然后其中一个人点击播放、暂停、拖动进度条时对房间中的其他人都实时生效。
可以在右边的聊天窗中进行发文本消息给房间中的所有人,房间中的其他人收到消息后,消息默认以弹幕的形式出现,像我们平时看直播的时候一样。当然,可以选择关闭弹幕。聊天窗也可以隐藏和重新显示。
开发中曾遇到的难题
1.在绑定QTcpSocket的readyRead信号到槽函数后,当频繁收到信号时,我在槽函数中做的事情很多,可能没有及时返回,就是比如第一次发射了信号,槽函数被第一次调用,然后槽函数第一次调用时还没执行完毕第二次信号又发射过来了,这时候我看到的现象是,槽函数没有第二次调用。这就引起:当房间中的某一方拖动进度条的时候,其他人没有实时更新到相应的进度。比如我从进度百分之5拖动到百分之30,对方客户端的readyRead信号发射了25次,但是槽函数只执行了20次,只收到了20个数据包,还有5个更新视频进度的数据包没有读出来,那么对方就只更新进度到百分之25
解决方法:采用多线程去读数据。弄一个信号量,初始值为0,当readyRead信号发射后,信号量值加3(比1大是因为防止数据又没读完,而且在线程中获得信号量后如果没有数据可读那么只需要进行2次额外的简单的判断工作,并没有消耗多大资源)。在QThread的run函数中acquire那个信号量,获得信号量后,调用QTcpSocket的bytesAvailable函数进行读数据包,收完一个完整的数据包后,先不去acquire信号量,先尝试再调用bytesAvailable函数看有木有数据可以再读,有的话就继续收,没有的话就阻塞等待获得信号量。
2.使用客户端软件的时候,时间长了总是莫名其妙的卡死,自己退出。但是显示的却是成功连接服务器,但是再也发不出数据,播放、暂停、拖动进度、发文本消息服务器都感知不到。(我是连接了QTcpSocket的stateChanged信号到槽函数的,状态变化的时候都会显示在标题栏上)。
一开始我的想法是,可能是双方都在看视频,很久没有在软件上进行一些操作,然后客户端就没有跟服务器有一些收发数据的交互,然后QTcpSocket就断开了。(根据测试,时间久了双方没有互动确实都会这样,但是如果有互动就没那么容易与服务器断开连接然后程序闪退)。当然了,这里面也有网络质量问题的原因。后来我连接了error信号到槽函数,发现每次卡死退出,error都是QAbstractSocket::RemoteHostClosedError,我这方面的知识有点欠缺,个人表示不知道为啥,查资料也没查出什么来,求大神指导指导。
解决方法:加入心跳包机制,客户端每5秒给服务器发一个心跳包,如果客户端连续两次没有发心跳包,那么服务器就主动断开连接。在客户端加入了断线重连机制,同时重连成功后自动恢复到之前的状态(登录,回到房间)。
经过改善后,再次使用,虽然图中还是会断线,在服务器端看到的是因为客户端没有按规定发心跳包所以服务器主动断开了客户端的连接,所以,可能还是网络状况的问题吧。客户端稳定了很多,没有再次出现卡死退出的现象,断线后会自动重连,使用时基本上没有什么问题了。
客户端有个功能没写:无法在全屏的状态下调节视频进度。因为时间原因,我没有继续开发了,因为考虑到只有自己和女友用到它,而且最近要学习新的东西,就先把时间花在学习新的东西上了,以后有空会继续完善。
客户端成品:
链接:https://pan.baidu.com/s/1_lDK4IuSvinCOK6Ii4hz4w
提取码:ao4j
如果有人有兴趣玩一下,那么欢迎。
希望大神不要攻击服务器,毕竟上面没有什么东西,我只是用来学习的,十分感谢~