「もう電話しないで、私に手紙を書かないでください!!!!」-SMSは私のガールフレンドのケイティから来ました。 数時間後、今は自由な時間がたくさんあることに気付き、DcoinをGoに移行することにしました。
はじめに
4.5年前、私はこのビジネスに完全に不適切な言語、つまりPHPで暗号通貨を書き始めるのは無謀でした。 結局、私は書きました(私は頑固です)が、松葉杖で松葉杖を手に入れました。それが一般的に機能するという事実は、ある種の魔法でした。
私はすぐにあなたに警告したいと思います、私は独学のプログラマーで、半学歴のあるプログラマーです、そして、それを穏やかに言えば、コードを書くことは理想的ではありません。
カティアで何が起こっているかに興味がある人のために、私はネタバレをしましたが、興味がない人はカティアに注意を払ってはいけません。
8か月の結果:アプリケーションは、Win( 64/32 )、OSX(64/32)、Linux(64/32)、FreeBSD(64/32)、 Android 、 IOS (誰かが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サーバーから-最も単純なものから始めることにしました。
楽しむ
説明によると、私は彼が何のためにあるのかよくわかりませんでした。 私はそれを置いて、実験し、それが明らかになりました-それは間違いなく適合しませんでした。 サイトを楽しむ。
ビーゴ
モジュールを搭載。 ロシア語には良いドックがあります。 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))で書き込み、ブラウザーに提供します。 まあ、そのようなもの。
セッション
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")
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)
どういうわけかそれをかき混ぜることにしました。 カティアは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: ""}))
夕方、私は本を読んで、何らかの理由で本のアドバイスを使って彼女が私に恋をしていることに気づきました。
次の部分に続きます。
おわりに
次の記事では、html /テンプレート、データベース、シグナルによるスムーズなアプリケーション完了、ブロックチェーンからのブロック処理、GOでの暗号化とJSでの復号化、gomobileを少し変更した方法、IOSの通知とバックグラウンド作業の追加について説明しますAndroidアプリ。