- 投稿日:2021-03-03T23:21:22+09:00
Go 言語でリバースプロキシ
Go 言語の標準ライブラリ
net/http/httputil
には、リバースプロキシを作るためのNewSingleHostReverseProxy
関数が用意されています。この関数を使うことで、Nginx で行うようなリバースプロキシを Go 言語のプログラム上で行うことができます。下記コードを実行して http://localhost:10000/ にアクセスすると、
hello, world
が返ってきます。ポート番号 10000〜10003 が使われていると正常に動作しないので注意が必要です。package main import ( "net/http" "net/http/httputil" "net/url" "time" "github.com/gin-gonic/gin" ) func main() { // サーバーを作成する s10000 := gin.Default() s10001 := gin.Default() s10002 := gin.Default() s10003 := gin.Default() // s10000 へのルートパスのリクエストは s10001 と s10002 を経由して s10003 に渡る s10000.GET("/", makeReverseProxy("10001")) s10001.GET("/", makeReverseProxy("10002")) s10002.GET("/", makeReverseProxy("10003")) s10003.GET("/", func(c *gin.Context) { c.String(http.StatusOK, "hello, world") }) // 非同期にサーバーを立ち上げる go s10000.Run(":10000") go s10001.Run(":10001") go s10002.Run(":10002") go s10003.Run(":10003") // プログラムが終わらないようにする time.Sleep(time.Hour) } func makeReverseProxy(port string) func(*gin.Context) { return func(c *gin.Context) { remote, _ := url.Parse("http://localhost:" + port) proxy := httputil.NewSingleHostReverseProxy(remote) proxy.ServeHTTP(c.Writer, c.Request) } }この仕組を使うことで、モノリシックな Web サーバーを複数の Web サーバーに分割できます。将来は複数のサーバーで運用したいけれど、とりあえずはひとつのサーバーで動かしたいといったときに使えるのではと思っています。
- 投稿日:2021-03-03T22:33:50+09:00
【Go言語】特定のTweetにリプライする
用意するもの
・PC(WindowsでもMacでも)
・Twitter API
・Twitterアカウントやったこと
1.Twitter API準備
色々な方が紹介されていると思いますので、割愛します。
2.Go言語で書く
処理としては、"ジャイアン"を含む自分の過去ツイートにリプライしています。
main.gopackage main import ( "fmt" "net/url" "strings" . "fmt" "github.com/ChimeraCoder/anaconda" ) //Twitter API認証用メソッド func GetTwitterApi() *anaconda.TwitterApi { anaconda.SetConsumerKey("API Key") anaconda.SetConsumerSecret("API secret Key") api := anaconda.NewTwitterApi("token", "token secret") return api } func main(){ api := GetTwitterApi() //Twitter認証処理呼び出し text := "おれさまがジャイアンだ!" //ツイート内容 v := url.Values{} v.Set("count", "10") //取得するツイート数をセット x := url.Values{} //リプライするツイート情報を格納する tweets, err := api.GetUserTimeline(v) //自分のタイムラインを10件取得 if err != nil { panic(err) } SearchText := "ジャイアン" //取得したツイートに対する処理 for i, tweet := range tweets { //ツイート内容にジャイアンが含まれているか if strings.Contains(tweet.FullText, SearchText) { id := tweets[i].IdSt x.Add("in_reply_to_status_id", id) //xにidを追加 } } tweet, err := api.PostTweet(text, x) if err != nil { panic(err) } fmt.Println("Finish!") }3.参考にしたドキュメント
anacondaで実装したい処理があればやはり公式ドキュメント見るのが一番いいと思いました。
次はいいねbot書きます~!
- 投稿日:2021-03-03T21:15:16+09:00
プログラミング超入門(2)〜GO言語〜
データ型について
変数に入れるデータの種類のことを指し、①数値型(number「ナンバー」型)②文字列型(string「ストリング」型) ③ブール型(Boolean「ブーリアン」型)に分けデータを代入する際に、Go言語ではデータ型として指定する静的型付け言語が用いられる。逆に、変数にデータを入れる際にデータを指定する必要がなく自動的に判断してくれるプログラミング言語を動的型付け言語といいます。
数値型には、整数型と小数点型がある
数値型 説明 int コンピューターで表せるだけの範囲の整数値を表す(int8 int32等、-127〜127) float64 64ビットのコンピューターで少数値を表す(32ビットの場合はfloat32型) ints.gopackage main import "fmt" func main() { var a int a = 4 b := 6 fmt.Println(2 * a) fmt.Println(b - a) }前回までの応用で、データ型を自動判別させ変数を定義して値を代入し実行してみます。
・実行結果
./ints 8 2
変数自身の値に処理を加える
変数は「変」数という名前から伝わるように、一度値を代入したあとでも別の値を再代入することができ、前にあった変数の値は新しく上書きされて消されます。例えば、
a := 100
の下にa = 50
と代入すれば、aの値は50になります。変数自身の値にを処理して、新しく代入する
変数の元の値を処理してその変数に代入し直す事ができます。
a = 50 (↓のaには値50が用いられる) (新しい値80が代入→)a = a + 30代入演算子の右側では、元の値が使われたうえで処理が行われます。そして、代入演算子の左側の変数に新しい演算子が代入される仕組みです。更に、
a = a + 30
はa += 30
のように省略して書くことができます。
省略形には、加算代入(+=)、減算代入(-=)、乗算代入(*=)、除算代入(/=)、剰余代入(%=)があります。ints.gopackage main import "fmt" func main() { a := 4 b := 6 fmt.Println(2 * a) fmt.Println(b - a) a = 50 b += a fmt.Println(a) fmt.Println(b) }変数自身の値を処理して再代入する処理を追記させて実行してみます。
・実行結果
./ints 8 2 50 56float64型の宣言を省略した書き方
a := 4.0
floats.gopackage main import "fmt" func main() { a := 4 fmt.Println(2 * a) fmt.Println(2.0 * a) fmt.Println(2.2 * a) }floats.goというファイルを作り、数値の型を確認してみます。
・実行結果
./floats 8 8 8.8
変数 a にはint型、変数 b にはfloat64型が渡されている場合、データ型の異なる値同士で減算するとエラーが乗じます。Go言語を始めとしたプログラミング言語の多くは、データ型が異なる数値同士での計算を禁じています。また、Go言語のデータ型は、reflect(リフレクト)のパッケージのTypeOf(タイプオフ)を使用して確認することが出来ます。nums.gopackage main import ("fmt" "reflect") func main() { num01 := 123 var num02 int = 123456789 num03 := 1.23 var num04 int = 1.23456789 fmt.Println(reflect.TypeOf(num01)) fmt.Println(reflect.TypeOf(num02)) fmt.Println(reflect.TypeOf(num03)) fmt.Println(reflect.TypeOf(num04)) }・実行結果
./nums int int float64 float64
- 投稿日:2021-03-03T20:19:00+09:00
string型にnilを入れる黒魔術
良いか悪いかといったら、どう考えても悪い。
package main import ( "fmt" ) type text struct { text string } func main() { var a string a = fmt.Sprint(nil) fmt.Println(a) fmt.Println(a == "nil") //fmt.Println(a == nil) //invalid operation: a == nil (mismatched types string and nil) var t text t.text = fmt.Sprint(nil) fmt.Println(t.text) fmt.Println(t.text == "nil") // fmt.Println(t == nil) // invalid operation: t == nil (mismatched types text and nil) }
- 投稿日:2021-03-03T15:18:58+09:00
VSCodeでbeegoをデバッグする
はじめに
beegoの学習中に、ブレークしようとしてVSCodeの←をぽちっとしてもぜんぜん止まらなかったのでメモ的に投稿。
前提
- windows環境
- beegoインストール済み
- vscodeインストール済み
- vscodeにgoの拡張機能インストール済み
delveをインストール
beegoプロジェクトのルートフォルダで下記実行。
$ go get -u github.com/derekparker/delve/cmd/dlv一応動作確認。下記がでればOK。
$ dlv version Delve Debugger Version: 1.5.1 Build: $Id: bca418ea7ae2a4dcda985e623625da727d4525b5 $launch.jsonを作成
VsCode上で実行タブを押下。
初回は実行ファイルを作成~がでるので押下して作成する。
すると以下のような感じになるはず。
このlaunch.jsonを下記のように変更する。
launch.json{ "version": "0.2.0", "configurations": [ { "name": "Launch", // "type": "godlvdap", "type": "go", "request": "launch", "mode": "auto", "program": "${workspaceFolder}/main.go", "env": {}, "args": [] } ] }programがポイントです。
beegoはmain.goを動作させたいので現在フォルダ以下のmain.goを指定。
他の詳細は以下を参考にしてください。Visual Studio CodeでGo言語のデバッグ環境を整える
ブレークポイントを追加&実行
後は他と同じようにブレークポイントを追加して、VSCode左上のlaunchの▷押下で実行。
処理を通れば無事デバッグできるはず。おわりに
新しい言語とかやると環境回りで時間とられるなー
- 投稿日:2021-03-03T06:25:44+09:00
Go Snippet: 最小限の JSON API サーバー
シンプルな JSON API サーバー。
コピペ用コード
package main import ( "encoding/json" "log" "net/http" ) type Post struct { ID int `json:"id"` Title string `json:"title"` Body string `json:"body"` } func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(&Post{ID: 1, Title: "hello", Body: "world"}); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }) log.Fatalln(http.ListenAndServe(":8080", nil)) }確認
ブラウザから
http://localhost:8080/
にアクセスする{ id: 1, title: "hello", body: "world" }
curl -i http://localhost:8080/
でアクセスするHTTP/1.1 200 OK Content-Type: application/json Content-Length: 40 {"id":1,"title":"hello","body":"world"}