毕业了我的三个超极客项目:一

本文介绍 毕业了我的三个超极客项目:一

毕业了我的三个超极客项目:一

This article was original written by Jin Tian, welcome re-post, first come with https://jinfagang.github.io . but please keep this copyright info, thanks, any question could be asked via wechat: jintianiloveu

硕士毕业了,记住本篇文章写作的日子(2018.05.18),离答辩刚刚结束一天,感谢我的研究生导师以及身边的人,日子不能如此闲着,于是决定在这段时间完成三个极客项目。对我来说,也许这才是能够体现能力的毕业设计的开始…

炫技的时候到了,三年研究生生涯,除了混迹于国内一些学术会议以外(国外神坛登不上),也在滴滴、腾讯这样的公司混迹过,不可谓阅历不深,主打的招牌还是计算机视觉算法,AI方向,但是这些真的够么?我觉得我们离真正的AI世界还很遥远,如果你一头扎进去,你可能就要和现实脱节了,现实世界依旧是互联网时代,很多事情可以通过互联网产品去改造,而AI只不过是其中的调味剂。未来真正大的突破,等待量子计算机的发展吧。

接下来的这三个超级极客项目,有点像灭霸收集宝石毁灭宇宙一半生命的感觉,这天道不公啊,我要逆天杀神…总的来说我想建造的东西非常简单:

  • 我需要一个真正的私人助理,不是聊天机器人不是聊天机器人不是聊天机器人,罗老师都说了把AI往智障聊天方向做本身就是一个错误的方向,那为什么我还要做私人助理呢?提高效率。。。我要把人类生活的效率提高200%…..开个玩笑,我想做的其实是就是一个CentralHub, 就像蝙蝠侠一样,我可以再我身边的每一个角落安插我的“机器人眼线”,他们的数据都可以汇总到我们的这个CentralHub上来,但是这个总不能非常low逼的用http请求把,所以说一个即时性的,消息中转处理中心就提上了议程,这个玩意一旦实现,也许我就可以从我的看家Arduino那里得知哪个小偷光顾了我家,以及可以从我的监控摄像头里面看到我想看到的东西;
  • 我需要不断地突破人类身体的局限,所以我们需要建造无人机,当然你也可以选择买一架magvic,但是我们是极客,都说了极客了,你买了那玩意能自己编程么?能自己写飞控么?能自己写PID算法么?能自己添加人脸识别跟踪算法么?自己造一个把;
  • 上天是令人刺激的,但是我想很多人想下水,水里面的世界可不比天上逊色多少啊。设想一下,我们的水下机器人你抛到河水或者大海里面去,它就可以自己去找鱼,然后冷不丁的把它电死,在放到自己的渔网里面去,一天下来,天快黑了,自动返航,然后带着一大袋子鱼…..有没有感觉像一个老老实实工作的小宠物? 好了,接下来我们开始吧这些上天入地的想法一一变成现实把

本文系列更新中,欢迎大家订阅。

闲话不多说了,这是一个系列文章,先列一下三个极客项目的名字(预定完成时间2018.5.18~2018.5.24):

  • Uranus(天王星): 一个聊天后端,一直以来我想脱离微信,做一个我自己的聊天机器人(微信机器人限制太多,QQ我又不太喜欢),干脆自己造聊天后端,这个完成之后或许可以作为一个很宏伟的创业项目,不敢轻易言说,但我觉得未来以聊天机器人为核心的社交应用会代替一部分微信的功能(比如一个bot每天给你发送新闻,你浏览朋友圈的时候, 可以顺便看到bot发的朋友圈:一个英文单词,对你来说资讯的流入是这么的让人印象深刻);
  • Enterprise(企业号): 造一架无人机….不会造无人机的硕士可以硕士不合格的硕士…微型无人机,目标是使用712或者408的小电机建造,但是名字叫做企业号..野心勃勃的无人机;
  • Dolphin(海豚):水下无人机器人..用来做什么?水下导航,上天入地么这不是…先挖个坑,以后有的是时间来填,不过我感觉要做完这些不是一点点时间需要花。。

Uranus

开始动工Uranus了。我不是开玩笑的,上面的每一个项目都非常有意义,而且及其重要,任何一个项目都可以发展为一个完整的创业项目。Uranus天王星项目的源代码可以在这里找到:https://github.com/jinfagang/uranus 我会不时的更新代码。

Uranus客户端最终完稿

最终的客户端效果图:

技术架构

这个肯定会用golang写,如果对golang不熟悉的朋友们就不用看下去了。我们要实现的功能包括:

  • 用户注册,用户需要一些信息;
  • 聊天功能的设计,最起码实现一个群聊和点对点聊天。使用websocket来解决这个问题,每个发送的信息都会带有token标识;

消息的设计:

  • hi: 上线的时候发送该请求,认证身份,一次会话只需要发送一次,如果未成功,则没有连接上服务器;
  • send: 发送到用户 或者群,实现,实际上全部集成到了send消息里面;
  • add: 添加好友或者是加入群,集成到一个方法;
  • del: 删除好友或者退出群,集成到一个消息;

十分简单,除此之外就没有了。

用户认证的实现

用户认证要做哪些事情呢?用户注册了,我需要头像和一些其他信息,然后我会根据ID生成一个token,这个token很关键啊。在hi消息里面要给到服务器,服务器根据hi来分配一个client。下次你就不要再发送hi了,直接send,send里面是你的target_id和content。

我发现golang写token生成真的十分蛋疼啊,来点干货把,这是生成token的代码:

// Claims is the content should to be encrypt
func Encrypt(infoMap map[string]interface{}) (string, error){
/*
claims are like this:
claims := &jwt.StandardClaims{
ExpiresAt: 15000,
Issuer: "test",}
*/
token := jwt.New(jwt.SigningMethodHS256)
claims := make(jwt.MapClaims)
claims["iss"] = iss
claims["iat"] = time.Now().Unix()
claims["exp"] = time.Now().Add(exp).Unix()
for k, v := range infoMap{
claims[k] = v
}
token.Claims = claims
ss, err := token.SignedString(mySalt)
return ss, err
}
func Decrypt(tokenStr string) (jwt.MapClaims, error) {
token, err := jwt.Parse(tokenStr, getValidationKey)
if err != nil {
return nil, TokenInvalid
}
if jwt.SigningMethodHS256.Alg() != token.Header["alg"] {
return nil, TokenInvalid
}
if !token.Valid {
return nil, TokenInvalid
}
claims := token.Claims.(jwt.MapClaims)
if claims["iss"] != iss {
return nil, TokenIllegal
}
return claims, nil
}

上面采用了一个叫做jwt-go的包。这样每次我的客户端发消息给我的时候,我就不用蛋疼的每次都查库看看这是谁了。

先实现点对点聊天

接下来得实现点对点聊天了。这个点对点聊天是基础的部分,但是如何实现呢?方法其实很简单,通过两个容器,一个clientsPool, 另一个msgQueue, 是一个消息队列,这个消息队列是有一个线程不断地去轮询消息,然后把消息发给所有的客户端,具体来说如下:

var clientsPool = make(map[string]*Client)
// msg queue are all the messages
var msgQueue = make(chan OutMsg)
type Client struct{
Conn *websocket.Conn
ClientAddr string
IsOnline bool
UA string
// client online time
UpTime int64
LastSeenTime int64
}
type OutMsg struct{
TargetAddr string
MsgType int
Payload interface{}
}

这里的TargetAddr是消息的目标地址,clientsPool实际上是一个客户连接池,也就是一个字典,它的key其实就是每个client的地址。通过索引地址就可以把消息写到websocket里面去。

听上去非常有道理,但是有一个严峻的问题来了:如果客户端没有在线,给没有在线的客户端发消息,如何保证它能收到离线的消息呢?换句话说,它上线的时候要能收到别人给它发的离线消息

实际上在上面的设计中,如果用户给他一个离线的客户端发了消息,那么它也是可以收到的。准确的来说,

最终设计的API文档可以如下:

## Login
the first step, you should login to uranus, this is because we have to got the token in our local, if we don't have token, you can not get access to uranus server.
For login, just call this api:

/api/v1/user_login

and send your `user_name` and `user_password`:

{
“user_name”: “lucasjin”,
“user_password”: “123123”,
}

And you will got a msg like welcome, you are login success now (if you wanna new an account, just register.)
## Send Msg
you want develop a new client, then you should probably want send msg to other clients, there are some `MsgType` you **must know**.
- `hi`: Hi msg for let server knows your client type and your user address, you will get your token and address when login;
- `send`: If you start to send msg, then using send msg type;
- `add`: msg for add into a group;
- `del`: delete a msg or you want leave a group or delete a person;
OK, that's all, those are all the msg type in **uranus** now.
Now, this is the all msg structure:
**{hi}**

{
“token”: “ehurhuoetihry.8u08954hggh.pguwtyh”,
“user_addr”: “usry7bvdgeug”,
“ua”: “uranus-0.1/PiLinux”,
“location”: “湖南长沙”,
“device”: “RaspberryPi”,
}

**{send}**

{
“target_addr”: “usry7u89ghutehu”,
“send_addr”: “usry7bvdgeug”,
“content”: “你他妈的还不回来吃午饭啊”,
“msg_type”: 0,
}

一切准备就绪,朋友们,见证奇迹的时刻到了!!

十天后的小成就

朋友们,你们通过Uranus已经拥有了一个像样的Wechat-Like APP! 让我们来预览一下:

还记得我之前做的聊天机器人吗?以前是依托于微信,现在可以完全自己实现一个随时随地汇报工作的机器人了!!!因为你有Uranus作为非常强大的通讯后盾。

十分简约,异乎寻常的简约。但是基本上可以实现一些功能了,不得不说这个意义重大。

很多人可能会觉得这个界面过于简单,如果你们有更好的建议可以再下面评论。

现成的APK下载

有新的朋友们可能会注意到,我用的是Flutter这个框架,这就牛逼了,我写了一套代码,可以同时生成android和ios客户端。非常强大。

后面我会把Uranus部署到服务端,然后给大家分享APK,甚至上线到appstore,但是在此之前,我想向大家征求一些比较牛逼的名字。

还需要完成的工作:

  • 聊天记录持久化
  • 头像支持
  • 离线消息接收
  • 图片消息发送的支持

实现玩这些,基本上就是一个小微信了。

未完待续….