12390


GoとWebsocketの練習として写真を投稿するWebアプリケーションを作っています。  
写真の投稿などはうまくできるのですが、  
一度、ブラウザがhtmlを読み込んだ後、もう一度ブラウザにhtmlを再読み込み(更新)させると、`websocket.JSON.Receive`が`EOF`となりServerが落ちてしまいます。  
なぜこのようなことが起こるのでしょうか?

ajaxを使ってもこのWeb Applicationは作れると思いますが、今回は練習のため、意図的にWebSocketを使いました。

Serverのコード

[code]

    
    package main
    
    import (
        "database/sql"
        "fmt"
        "github.com/go-gorp/gorp"
        _ "github.com/mattn/go-sqlite3"
        "golang.org/x/net/websocket"
        "log"
        "net/http"
    )
    
    type Picture struct {
        Id   int64
        Data []byte
        Name string
    }
    
    var debug = true
    
    var photodb = "./db/photo.sqlite3"
    
    func main() {
        http.Handle("/layouts/css/", http.StripPrefix("/layouts/css/", http.FileServer(http.Dir("layouts/css"))))
        http.HandleFunc("/chat", func(w http.ResponseWriter, req *http.Request) {
            s := websocket.Server{Handler: websocket.Handler(data_handle)}
            s.ServeHTTP(w, req)
        })
        fmt.Println(":8249")
        http.ListenAndServe(":8249", nil)
    }
    
    func InitDb() (*gorp.DbMap, error) {
        db, err := sql.Open("sqlite3", photodb)
        if err != nil {
            fmt.Println(err)
            return nil, err
        }
        dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
        dbmap.AddTableWithName(Picture{}, "picture").SetKeys(true, "Id")
        err = dbmap.CreateTablesIfNotExists()
        if err != nil {
            return nil, err
        }
        return dbmap, nil
    }
    
    func insertPic(pic *Picture) {
        dbmap, err := InitDb()
        if err != nil {
            log.Fatalln("InitDb error:", err)
        }
        err = dbmap.Insert(pic)
        if err != nil {
            log.Fatalln("Insert error:", err)
        }
    }
    
    func data_receive(ws *websocket.Conn) {
        for {
            var b Picture
            if err := websocket.JSON.Receive(ws, &b); err != nil {
                if debug {
                    fmt.Println(b)
                }
                log.Fatalln("Receive error: ", err)
            } else {
                insertPic(&b)
                err = websocket.JSON.Send(ws, b)
                if err != nil {
                    fmt.Println("Send error:", err)
                }
            }
        }
    }
    
    func data_handle(ws *websocket.Conn) {
        data_receive(ws)
    }
    
    
    
    
[/code]

JavaScript

[code]

    
    var ws = new WebSocket("ws://localhost:8249/chat")
    var img = document.getElementById("img");
    var f = document.getElementById("file");
    var file_reader = new FileReader();
    f.onchange = function () {
        var filelist = this.files;
        var file = filelist[0];
        file_reader.onload = function (e) {
            var data = e.target.result;
            var b64 = data.slice(data.indexOf(",") + 1);
            var s = {"Name": file.name, "Data": b64};
            console.log(s);
            ws.send(JSON.stringify(s));
    
        }
        file_reader.readAsDataURL(file);
    
    }
    
    ws.onmessage = function (e) {
        var obj = console.log(e.data);
    
    }
    
    
    
    
[/code]

html

[code]

    
    <!DOCTYPE html>
    <html lang="ja">
        <head>
            <title>Websocket json</title>
            <meta charset="utf-8">
        </head>
        <body>
            <input type="file" id="file" accept="image/*">
            <img id="img">
            <script src="websocket_json.js"></script>
        </body>
    </html>
    
    
[/code]


CC BY-SA 3.0
2015-07-15T13:34:45.443
12389
2015-07-15T13:46:12.393
5246
question
javascript html go websocket
Golangでページを再読み込みするとWebsocket Serverが落ちる


画面をリロードすると一旦接続が切れるため、`Receive`は`EOF`を返します。  
これは正常な動作なので、エラーは出さずにループを抜けてください。

サーバーが落ちるのは`log.Fatalln`を使っているせいです。  
この関数はメッセージを表示したあと、自動的にプログラムを異常終了させます。  
名前の通り致命的なエラーが発生した時に使ってください。


CC BY-SA 3.0
2015-07-15T13:46:12.393
12390
2015-07-15T13:46:12.393
3639
12389
answer