[hplayer] [Music server="netease" id="409872504" type="song"/] [/hplayer] # 说明 因为这个项目是公司要求私有的,不允许写在公开仓库上,这里也不说其他的了,只说设计的技术栈和经验 这只是整个服务的一个小细分,功能也很重要。 # 项目技术栈 [goal title="技术细分"] [item check="true"]Go[/item] [item check="true"]Redis[/item] [item check="true"]Mysql[/item] [item check="true"]File io流[/item] [item check="true"]Gin后端服务[/item] [item check="true"]文件打包成xlsx[/item] [item check="true"]http请求和各类结果转化json的情况[/item] [item progress="80%"] 我负责的部分 [/item] [item progress="99.99%"] 项目当前进度 [/item] [/goal] --- # 讲讲遇到的坑 ### Go读取配置文件,配置文件必须放在同一级目录,或者在同级目录里有一个叫config文件夹里面 [scode type="blue"]配置文件通常放在config目录里面[/scode] --- ### Go请求和获取的数据当是json时请转化为结构体,或者直接用包格式化字符串 如像这样: ``` data := "{\r\n \"Socks5\": \"%s\",\r\n \"EdgeRouting\": \"CA0IBQ==\",\r\n \"AuthBody\": {\r\n \"username\": %s,\r\n \"passive\": false,\r\n \"user_agent\": {\r\n \"platform\": 0,\r\n \"app_version\": {\r\n \"primary\": 2,\r\n \"secondary\": 21,\r\n \"tertiary\": 12,\r\n \"quaternary\": 22\r\n },\r\n \"mcc\": \"310\",\r\n \"mnc\": \"070\",\r\n \"os_version\": \"7.1.2\",\r\n \"manufacturer\": \"samsung\",\r\n \"device\": \"fortunave32\",\r\n \"os_build_number\": \"google-user 7.1.2 20171130.276299 release-keys\",\r\n \"phone_id\": \"%s\",\r\n \"locale_language_iso_639_1\": \"en\",\r\n \"local_country_iso_3166_1_alpha_2\": \"US\",\r\n \"Brand\": \"msm8998\"\r\n },\r\n \"push_name\": \"sjeyg\",\r\n \"short_connect\": false,\r\n \"connect_type\": 1,\r\n \"Tag23\": 1\r\n },\r\n \"AuthHexData\": \"\",\r\n \"StaticPriKey\": \"%s\",\r\n \"StaticPubKey\": \"%s\"\r\n}" data = fmt.Sprintf(data, logins.Socks5, login, logins.PhoneId, logins.StaticPriKey, logins.StaticPubKey) resp, err := http.Post(api, "application/json", strings.NewReader(data)) ``` 这里使用%s作为字符串替换,关于字符串格式化那张可以看这篇文章 [post cid="321" cover=""/] 这里遇见了一个小坑,如:  这里可以发现他的有一个特殊的类型,interface,这个类型会让编辑器自动判断接收的类型,这里我们就不能正常的获取他的值了,单纯的json包也不行,不过这里有个包可以解决这个问题。 ``` "github.com/mitchellh/mapstructure" ``` 它的使用场景是把已经解析的部分json数据,其中嵌套的json结果转化,如这种情况: { ``` "Code": 0, "Data": { "count": 1, "ws": [ {**** "loginState": "", "userName": "*****" } ] }, "Msg": null } ``` 在Go中获取Data.ws里面的数据就很麻烦,所以需要用到这个包,当然通过断言也可以做到,不过我这里就讲讲这个包的解决方法--- 使用这个包很好解决,首先定义结构体 ``` type InfoWS struct { LoginState string `mapstructure:"loginState" json:"login_state"` UserName string `mapstructure:"UserName" json:"user_name"` } ``` 然后使用这个包的转化语句,weak是指的是弱类型,而没有就是强类型,需要注意报错 ver 是InfoWS的内容 ``` if err := mapstructure.WeakDecode(result.Data, &ver); err != nil { logrus.Error("转化结构体出错--->", err) } ``` --- ### Go协程造成的并发变量抢占 这个则需要异步锁来解决这个问题  --- ### Go使用goto 语句 [scode type="blue"]非常不建议使用goto语句!!![/scode] 我使用这个语句的想法是将当前这个流程判断中错误后回到起始,我不可能使用for语句,太过麻烦,而且也很不美观,于是就使用goto语句了。 我们需要在想要重新开始流程的代码前面加上标签,如这里的标签是LOOP ``` go func(phones []string) { // 开始筛选 LOOP: phone := inWs.RandList() if phone == "" goto LOOP } ``` 当使用goto语句就会跳到LOOP这个标签里的代码了。 如果不是特殊情况请勿使用goto语句,臭名昭著的东西 --- 剩下的就是简单的mysql,web框架gin的简单使用,redis和任务列表之类的,这些就不讲了。 --- 写了这个项目对自己的收获很大。 --- Loading... <div class='handsome_aplayer player-content' data-preload="auto" data-autoplay="false" data-listMaxHeight="340px" data-order="list"> <div class="handsomePlayer-tip-loading"><span></span> <span></span> <span></span> <span></span><span></span></div><div class="handsome_aplayer_music" data-id="409872504" data-server="netease" data-type="song" data-auth="9814991f6f33240ad42c062e13252471"></div> </div> # 说明 因为这个项目是公司要求私有的,不允许写在公开仓库上,这里也不说其他的了,只说设计的技术栈和经验 这只是整个服务的一个小细分,功能也很重要。 # 项目技术栈 <div class="panel panel-default box-shadow-wrap-lg goal-panel"> <div class="panel-heading"> 技术细分 </div> <div class="list-group"> <div class="list-group-item"><div class="checkbox"> <label class="i-checks"> <input type="checkbox" checked="" disabled="" value=""> <i></i> Go </label> </div><div class="checkbox"> <label class="i-checks"> <input type="checkbox" checked="" disabled="" value=""> <i></i> Redis </label> </div><div class="checkbox"> <label class="i-checks"> <input type="checkbox" checked="" disabled="" value=""> <i></i> Mysql </label> </div><div class="checkbox"> <label class="i-checks"> <input type="checkbox" checked="" disabled="" value=""> <i></i> File io流 </label> </div><div class="checkbox"> <label class="i-checks"> <input type="checkbox" checked="" disabled="" value=""> <i></i> Gin后端服务 </label> </div><div class="checkbox"> <label class="i-checks"> <input type="checkbox" checked="" disabled="" value=""> <i></i> 文件打包成xlsx </label> </div><div class="checkbox"> <label class="i-checks"> <input type="checkbox" checked="" disabled="" value=""> <i></i> http请求和各类结果转化json的情况 </label> </div> <p class="goal_name"> 我负责的部分 :</p> <div class="progress-striped active m-b-sm progress" value="dynamic" type="danger"> <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="97" aria-valuemin="0" aria-valuemax="100" style="width: 80%;"><span> 80% </span></div> </div> <p class="goal_name"> 项目当前进度 :</p> <div class="progress-striped active m-b-sm progress" value="dynamic" type="danger"> <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="97" aria-valuemin="0" aria-valuemax="100" style="width: 100%;"><span> 100% </span></div> </div></div></div></div> --- # 讲讲遇到的坑 ### Go读取配置文件,配置文件必须放在同一级目录,或者在同级目录里有一个叫config文件夹里面 <div class="tip inlineBlock info"> 配置文件通常放在config目录里面 </div> --- ### Go请求和获取的数据当是json时请转化为结构体,或者直接用包格式化字符串 如像这样: ``` data := "{\r\n \"Socks5\": \"%s\",\r\n \"EdgeRouting\": \"CA0IBQ==\",\r\n \"AuthBody\": {\r\n \"username\": %s,\r\n \"passive\": false,\r\n \"user_agent\": {\r\n \"platform\": 0,\r\n \"app_version\": {\r\n \"primary\": 2,\r\n \"secondary\": 21,\r\n \"tertiary\": 12,\r\n \"quaternary\": 22\r\n },\r\n \"mcc\": \"310\",\r\n \"mnc\": \"070\",\r\n \"os_version\": \"7.1.2\",\r\n \"manufacturer\": \"samsung\",\r\n \"device\": \"fortunave32\",\r\n \"os_build_number\": \"google-user 7.1.2 20171130.276299 release-keys\",\r\n \"phone_id\": \"%s\",\r\n \"locale_language_iso_639_1\": \"en\",\r\n \"local_country_iso_3166_1_alpha_2\": \"US\",\r\n \"Brand\": \"msm8998\"\r\n },\r\n \"push_name\": \"sjeyg\",\r\n \"short_connect\": false,\r\n \"connect_type\": 1,\r\n \"Tag23\": 1\r\n },\r\n \"AuthHexData\": \"\",\r\n \"StaticPriKey\": \"%s\",\r\n \"StaticPubKey\": \"%s\"\r\n}" data = fmt.Sprintf(data, logins.Socks5, login, logins.PhoneId, logins.StaticPriKey, logins.StaticPubKey) resp, err := http.Post(api, "application/json", strings.NewReader(data)) ``` 这里使用%s作为字符串替换,关于字符串格式化那张可以看这篇文章 <div class="preview"> <div class="post-inser post box-shadow-wrap-normal"> <a href="https://www.yuhenm.top/archives/321.html" target="_blank" class="post_inser_a no-external-link no-underline-link"> <div class="inner-image bg" style="background-image: url(https://www.yuhenm.top/usr/uploads/2021/10/3880703322.png);background-size: cover;"></div> <div class="inner-content" > <p class="inser-title">python 的string 章节详解</p> <div class="inster-summary text-muted"> python中定义一个字符串变量:# 单行字符串 val = "name" vals = '... </div> </div> </a> <!-- .inner-content #####--> </div> <!-- .post-inser ####--> </div> 这里遇见了一个小坑,如:  这里可以发现他的有一个特殊的类型,interface,这个类型会让编辑器自动判断接收的类型,这里我们就不能正常的获取他的值了,单纯的json包也不行,不过这里有个包可以解决这个问题。 ``` "github.com/mitchellh/mapstructure" ``` 它的使用场景是把已经解析的部分json数据,其中嵌套的json结果转化,如这种情况: { ``` "Code": 0, "Data": { "count": 1, "ws": [ {**** "loginState": "", "userName": "*****" } ] }, "Msg": null } ``` 在Go中获取Data.ws里面的数据就很麻烦,所以需要用到这个包,当然通过断言也可以做到,不过我这里就讲讲这个包的解决方法--- 使用这个包很好解决,首先定义结构体 ``` type InfoWS struct { LoginState string `mapstructure:"loginState" json:"login_state"` UserName string `mapstructure:"UserName" json:"user_name"` } ``` 然后使用这个包的转化语句,weak是指的是弱类型,而没有就是强类型,需要注意报错 ver 是InfoWS的内容 ``` if err := mapstructure.WeakDecode(result.Data, &ver); err != nil { logrus.Error("转化结构体出错--->", err) } ``` --- ### Go协程造成的并发变量抢占 这个则需要异步锁来解决这个问题  --- ### Go使用goto 语句 <div class="tip inlineBlock info"> 非常不建议使用goto语句!!! </div> 我使用这个语句的想法是将当前这个流程判断中错误后回到起始,我不可能使用for语句,太过麻烦,而且也很不美观,于是就使用goto语句了。 我们需要在想要重新开始流程的代码前面加上标签,如这里的标签是LOOP ``` go func(phones []string) { // 开始筛选 LOOP: phone := inWs.RandList() if phone == "" goto LOOP } ``` 当使用goto语句就会跳到LOOP这个标签里的代码了。 如果不是特殊情况请勿使用goto语句,臭名昭著的东西 --- 剩下的就是简单的mysql,web框架gin的简单使用,redis和任务列表之类的,这些就不讲了。 --- 写了这个项目对自己的收获很大。 --- 最后修改:2021 年 10 月 22 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏