暗号通貨をPHPからGoに8か月間書き直した方法。 パート1





「もう電話しないで、私に手紙を書かないでください!!!!」-SMSは私のガールフレンドのケイティから来ました。 数時間後、今は自由な時間がたくさんあることに気付き、DcoinをGoに移行することにしました。









はじめに



4.5年前、私はこのビジネスに完全に不適切な言語、つまりPHPで暗号通貨を書き始めるのは無謀でした。 結局、私は書きました(私は頑固です)が、松葉杖で松葉杖を手に入れました。それが一般的に機能するという事実は、ある種の魔法でした。

私はすぐにあなたに警告したいと思います、私は独学のプログラマーで、半学歴のあるプログラマーです、そして、それを穏やかに言えば、コードを書くことは理想的ではありません。



カティアで何が起こっているかに興味がある人のために、私はネタバレをしましたが、興味がない人はカティアに注意を払ってはいけません。









8か月の結果:アプリケーションは、Win( 64/32 )、OSX(64/32)、Linux(64/32)、FreeBSD(64/32)、 AndroidIOS (誰かがApp Storeにドロップするとクールになります)で実行されます)

合計コードは約73k行で、異なるOSのコードは数百行程度です。

40k-処理/ブロック生成/ tr-17、17.5k-インターフェース用コントローラー、15.5k-テンプレート

PostgreSQL、SQLite、MySQLがサポートされています。









私の作品をテストする人に警告します-バグがあるかもしれません。時間があれば、 darwin @ dcoin.clubまたはハブのPMでそれらについて書いてください。 提案やアドバイスも歓迎します。









さて、今、私はこのすべてをどのように書いたか、新しいことを学んだことなどを私の話をします。誰かが自分の記事から自分に役立つ何かを引き出してくれることを望みます。









開始する



KatiでのSMSから数時間経過しました。 Dcoinを書き換える決定はすでに下されています。 どこかから始める必要がありました。 Goをゼロから学習する方法をグーグルで学習し始めました。 http://golang-book.ru/https://tour.golang.org/を 2〜3日間勉強した後、 この本をダウンロードしました。約2週間かかりました。例を実行しただけで、自分でやったことがあります仕事を逃した。 それは困難でしたが、面白かったです。 できるだけ早くPHPソースの書き直しを開始したかったのです。









私は長い間新しいものを研究していません。私の脳はそのようなレジメンに慣れていません。 薬局でOmega-3とNootropilを購入しました。自己催眠の可能性がありますが、それらの下のinfaを覚えておく方が良いです。









最後の章を読みました。 最後に、最も興味深いものに進むことができました。

タスクは非常に理解しやすいものです。数万行のPHPコードを書き換えることです。 しかし、どこから始めるべきかは完全に不明確です。 Webサーバーから-最も単純なものから始めることにしました。









Katyaについて
まず、それがどのように始まったのかを説明します。 私は2015年初めに出会い系サイトでインターネットで彼女に会った。 すぐに恋に落ちました。 外部的には、彼女は私の好みに合っていました。 私たちは公園を歩き回り、冗談を言い、笑い、ピン留めし、寒くなりました、私は別れたくありませんでした。 漫画を見るために電話しました。 タクシーに乗って到着しました。 彼は非常に面白い漫画である「3人のヒーロー:乗馬」をオンにし、ベッドに横たわって、涙を浮かべて笑いました。




楽しむ



説明によると、私は彼が何のためにあるのかよくわかりませんでした。 私はそれを置いて、実験し、それが明らかになりました-それは間違いなく適合しませんでした。 サイトを楽しむ。









ビーゴ



モジュールを搭載。 ロシア語には良いドックがあります。 2つの構成モジュールとセッションモジュールを取りました。









ゴリラ



muxは良いことですが、アプリケーションを見つけることができませんでした。









その結果、純粋なネット/ http + html /テンプレートに落ち着きました









Webサーバー



GoでWebサーバーを上げるのは簡単です。 ファイルサーバーの例を次に示します。







package main import "net/http" func main() { changeHeaderThenServe := func(h http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { h.ServeHTTP(w, r) } } http.Handle("/", changeHeaderThenServe(http.FileServer(http.Dir(".")))) http.ListenAndServe(":8000", nil) }
      
      





簡単にするために、エラー処理は削除されました。 8000番目のポートには、アプリケーションを実行しているディレクトリのルートリストがあり、ファイルをダウンロードできます。

コントローラーを名前で呼び出す



170個のコントローラーを入手しました。 各コントローラーは、content.goなどの6つのHandleFuncの1つを介して呼び出されます。 HandleFuncのコントローラー名は、このtplName:= r.FormValue( "tpl_name")のようなPOSTまたはGETリクエストから取得されます。 次に、 CallController(c、tplName)が呼び出され、170個のコントローラーの1つを呼び出します。このコントローラーは、完成したhtmlコードを提供し、content.goはHTMLを受け取り、w.Write([]バイト(html))で書き込み、ブラウザーに提供します。 まあ、そのようなもの。









Katyaについて
夕方、私はカティアが夜を過ごすと確信しています。 しかし、何らかの理由で、彼女は家に帰る必要があると繰り返し始めました。 ベッドで彼女の朝食を食べたいと言った。 明日の朝に彼女が朝食をとるように手配してください。 私はタクシーを呼んだ、彼女は去った。 私は幸せに眠りました 私は自分自身が美しい女の子で、面白くて面白かったです。 翌日、テキストメッセージ「こんにちは。 何してるの?」 私は自分の気持ちを覚えています。私は本当に好きな女の子を書いたので、楽しかったです。 そしてすぐに私たちは彼女と再び会うことになりました...





セッション



beegoのセッションモジュールのおかげで、すべてが非常に簡単です









 //      ,        globalSessions, _ = session.NewManager("memory", `{"cookieName":"gosessionid","gclifetime":86400}`) go globalSessions.GC() //    sess.Set("username", 1000) sess, _ := globalSessions.SessionStart(w, r) defer sess.SessionRelease(w) //    username := sess.Get("username")
      
      







ファイル処理



upload_video.goコントローラー 、ファイルを受け入れる必要がありました。







 //    . 32Mb r.ParseMultipartForm(32 << 20) //    multipart.File file, _, _ := r.FormFile("file") buffer := new(bytes.Buffer) //    _, err = io.Copy(buffer, file) defer file.Close() //   binaryFile = buffer.Bytes() //   fileName := r.MultipartForm.File["file"][0].Filename // Content-Type contentType := r.MultipartForm.File["file"][0].Header.Get("Content-Type")
      
      







クライアントから3gpを受信して​​mp4を返すサーバーのコード(突然誰かのために役立つでしょう)
 package main import ( "io" "io/ioutil" "fmt" "net" "github.com/c-darwin/dcoin-go/packages/utils" "os" "os/exec" ) func handleRequest(conn net.Conn) { //   buf := make([]byte, 4) n, err := conn.Read(buf) if err != nil { fmt.Printf("%v", utils.ErrInfo(err)) } size := utils.BinToDec(buf) fmt.Printf("get data size: %v / n: %v\n", size, n) if size < 10485760 { //   binaryData := make([]byte, size) n, err = io.ReadFull(conn, binaryData) fmt.Printf("n: %v\n", n) if err != nil { fmt.Printf("%v", utils.ErrInfo(err)) } gp3, err := ioutil.TempFile(os.TempDir(), "temp") if err != nil { fmt.Printf("%v", utils.ErrInfo(err)) } mp4, err := ioutil.TempFile(os.TempDir(), "temp") if err != nil { fmt.Printf("%v", utils.ErrInfo(err)) } err = ioutil.WriteFile(gp3.Name()+".3gp", binaryData, 0644) if err != nil { fmt.Printf("%v", utils.ErrInfo(err)) } out, err := exec.Command("/usr/bin/ffmpeg", "-i", gp3.Name()+".3gp", mp4.Name()+".mp4").Output() if err != nil { fmt.Println("/usr/bin/ffmpeg", "-i", gp3.Name()+".3gp", mp4.Name()+".mp4") fmt.Printf("%v\n", utils.ErrInfo(err)) } fmt.Printf("out: %v\n", out) data, err := ioutil.ReadFile(mp4.Name()+".mp4") if err != nil { fmt.Println(err) } //  4-    ,    size := utils.DecToBin(len(data), 4) n, err = conn.Write(size) if err != nil { fmt.Println(err) } fmt.Printf("n: %v\n", n) //     n, err = conn.Write(data) if err != nil { fmt.Println(err) } fmt.Printf("n: %v\n", n) } } func main() { //   TCP-     l, err := net.Listen("tcp", ":8099") if err != nil { fmt.Printf("Error listening: %v\n", err) panic(err) os.Exit(1) } defer l.Close() for { conn, err := l.Accept() if err != nil { fmt.Println("Error accepting: ", err.Error()) os.Exit(1) } go handleRequest(conn) } }
      
      









Base64を画像に変換する



crop_photo.goでは 、base64で写真を撮り、そこから通常のpngを取得する必要がありました









 b64, _ := base64.StdEncoding.DecodeString(r.FormValue("b64Img")) img, _, _ := image.Decode(bytes.NewReader(b64)) out, _ := os.Create("img.png") //  img.png    png.Encode(out, img)
      
      





Katyaについて
その日は会ったことがない。 そして次も。 彼女の頭の中で何が起こっているのかわかりませんが、彼女は絶えずデートに耐えました。 2月23日には祝福すらしませんでした。

どういうわけかそれをかき混ぜることにしました。 カティアはSMSを書きました:「私はすぐに、もちろん私はキャプチャします」

彼女は答えました:「ある意味で?」

私:「おっと、ない」

彼女:「そうです」

彼女のjeはオンになりました。 1日後、会うように招待され、彼女は同意した。




Bindata



Webサーバーをコンパイルしてノードの1つに転送したとき、何も機能しませんでした。 すべてのテンプレート、画像など自体がバイナリにパックされていないことが判明しました。







Googled、 https://github.com/jteeuwen/go-bindataが見つかりました







タルサは非常に便利でシンプルです。テンプレート、画像などが一連のバイトとして変数に書き込まれるgoファイルを生成します。 その結果、コンパイル後に1つのバイナリが取得されます。









ファイルをディスクから取得する場合は、オプション「-debug = true」を追加する必要があります。

毎回goファイルを配置するパスを入力しないように、単純なbashスクリプトを使用します









 #!/bin/bash if [ $# -gt 0 ] && [ $1 = "debug" ] then DEBUG="-debug=true" fi go-bindata -o="packages/static/static.go" -pkg="static" $DEBUG static/...
      
      





次に、 localhostリクエストで静的ディレクトリからファイルを受信できるようにする必要がありました:8089 / static / img.png。 これにはgo-bindata-assetfsがあります 。 静的ディレクトリの例を次に示します。



 http.Handle("/static/", http.FileServer(&assetfs.AssetFS{Asset: static.Asset, AssetDir: static.AssetDir, Prefix: ""}))
      
      





Katyaについて
彼女の行動を分析し、少しグーグルで調べた後、私はこの本に出くわしました新しい規則。現代の女の子のための成功した関係の秘密

夕方、私は本を読んで、何らかの理由で本のアドバイスを使って彼女が私に恋をしていることに気づきました。

次の部分に続きます。




おわりに



次の記事では、html /テンプレート、データベース、シグナルによるスムーズなアプリケーション完了、ブロックチェーンからのブロック処理、GOでの暗号化とJSでの復号化、gomobileを少し変更した方法、IOSの通知とバックグラウンド作業の追加について説明しますAndroidアプリ。








All Articles