以下の記述は間違っているようですので、参照にしないで下さい(現在検証中)。
(昨日、ソフト外注会社の方に教えて貰いました)
Golangで、http.HandleFunc と http.Handleについて、ずっと混乱しつづけています。
というか、私は、使い方が分かればよくて、その理屈なんぞ1mmも興味がないので、コードを書きながら理解しています(結局、遅くなっているような気がしますが)。
1. http.Handle()は、index.htmlをベースとしたサーバを立てるもの
// main16.go 現在の居場所は、c:\Users\ebata\hirohakama\199A2\others
/*
.
├── main16.go
├── index.html (A)
└── chart            # chartフォルダに静的ファイルがある
    └── index.html (B)
*/
package main
import (
	"net/http"
)
func main() {
	// 静的ファイル配信.
	// ディレクトリ名をURLパスに使う場合
	// 例:http://localhost:8080/chart/で index.html (B) の方を表示
	http.Handle("/chart/", http.FileServer(http.Dir("./")))
	// 例:http://localhost:8080/で index.html (A) の方を表示
	http.Handle("/", http.FileServer(http.Dir("./")))
	// ディレクトリ名とURLパスを変える場合
	// 例:http://localhost:8080/mysecret/sample1.txt
	// http.Handle("/mysecret/", http.StripPrefix("/mysecret/", http.FileServer(http.Dir("./contents"))))
// 例:http://localhost:8080/で index.html (A) の方を表示
	http.Handle("/", http.FileServer(http.Dir("./")))
	// 8080ポートで起動
	http.ListenAndServe(":8080", nil)
}
これで、main16.goが置いている場所が、基準点となります(それだけです)。
で、色々考えずに、基本は、
	http.Handle("/", http.FileServer(http.Dir("./")))
としておきましょう(というか、これがデフォルトなら、記載すらしなくてもいい)
2. http.HandleFunc()は、ソースコードで書いたものをサーバとするもの
// main15.go 現在の場所はc:\Users\ebata\hirohakama\199A2\others
/*
.
└── main15.go
*/
package main
import (
	"io"
	"log"
	"net/http"
)
func h1(w http.ResponseWriter, _ *http.Request) {
	io.WriteString(w, "Hello from a HandleFunc #1!\n")
}
func h2(w http.ResponseWriter, _ *http.Request) {
	io.WriteString(w, "Hello from a HandleFunc #2!\n")
}
func main() {
	// http://localhost:8080/ で h1の内容を表示 (プログラムの内容を)
	http.HandleFunc("/", h1)
	// http://localhost:8080/endpoint で h2の内容を表示
	http.HandleFunc("/endpoint", h2)
	log.Fatal(http.ListenAndServe(":8080", nil))
}
3. http.Handle()1つとhttp.handleFunc()1つが混在しているものは、それぞれサーバが2つある、ということ
// main13.go
package main
import (
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"time"
	"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{}
type GetLoc struct {
	ID    int     `json:"id"`
	Lat   float64 `json:"lat"`
	Lng   float64 `json:"lng"`
	TYPE  string  `json:"type"` // "PERSON","BUS","CONTROL
	POPUP int     `json:"popup"`
	//Address string  `json:"address"`
}
func echo3(w http.ResponseWriter, r *http.Request) {
	upgrader.CheckOrigin = func(r *http.Request) bool { return true } // おまじない
	conn2, err := upgrader.Upgrade(w, r, nil) //conn2でwebsocketを作成
	if err != nil {
		log.Println("websocket connection err:", err)
		return
	}
	defer conn2.Close()
	for {
		gl2 := new(GetLoc)
		gl2.ID = rand.Intn(20) // ここで乱数を発生されて、javascriptで受信させる
		gl2.Lat = 181.0
		gl2.Lng = 181.0
		gl2.TYPE = "BUS"
		gl2.POPUP = 101
		err := conn2.WriteJSON(&gl2)
		if err != nil {
			log.Println("ReadJSON:", err)
			break
		}
		fmt.Println("echo3:", gl2)
		time.Sleep(time.Second * 1)
	}
}
//var addr = flag.String("addr", "0.0.0.0:5000", "http service address") // テスト
func main() {
	http.Handle("/chart/", http.FileServer(http.Dir("./")))
	http.HandleFunc("/echo3", echo3)
	//log.Println("server starting...", "http://localhost:8080")
	//log.Fatal(http.ListenAndServe("localhost:8080", nil))
	log.Fatal(http.ListenAndServe(":8080", nil))
}
index.html
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>test</title>
</head>
<script type="text/javascript" src="moment.js"></script>
<script type="text/javascript" src="Chart.js"></script>
<script type="text/javascript" src="chartjs-plugin-streaming.js"></script> 
<script>  
    var ws;
    // websocketのオープン(この段階で接続完了)
    ws = new WebSocket('ws://localhost:8080/echo3')  // ユーザ登録画面
    ws.onopen = function (event) {
    }
    ws.onmessage = function (event) {
        // 送られてきたデータを受信して、JSON形式に変更
        var obj = JSON.parse(event.data);
        console.log("obj:",obj);
        console.log("obj.id:",obj.id);
        aa = obj.id;
    }
</script>  
<body BGCOLOR="black" text="white"  STYLE="overflow: hidden;">
	<center>
	  <font size="5">Waking Time(min.) <br></font> <!--- 意味のない表示 -->
	  <font size="5"> 歩行時間(分)</font> <!--- 意味のない表示 -->
	</center>
	
    <canvas id="myChart" width="100" height="85"></canvas>
<script>  
    var ctx = document.getElementById('myChart').getContext('2d');
			var chart = new Chart(ctx, {
				type: 'line',
				data: {
					datasets: [{
                        data: [],  // 1つめ
                        borderColor: "rgba(255,0,0,1)",
                        backgroundColor: "rgba(0,0,0,0)",  
                        lineTension: 0,
                        label: 'Time',
					}]
				},
				options: {
					scales: {
						xAxes: [{
                            type: 'realtime',
                            realtime: {
                                duration: 30000, // 300000ミリ秒(5分)のデータを表示 (コメントアウトすると早く動く)
                                onRefresh: function(chart) {
                                    chart.data.datasets.forEach(function(dataset) {
                                        dataset.data.push({
                                            x: Date.now(),
                                            //y: (Math.floor(Math.random()*16)+30) //30-45の乱数(整数)
                                            y: aa, // この"aa"が、送られてきたデータ
                                        });
                                    });
                                }
                            }
                        }],
                        yAxes: [{
					        ticks: {
					        	max: 20,
					        	min: 0
        					}
                        }]
					}
				}
			});
</script>
</body>
</html>
この場合、
- /chart/index.htmlをベースとするサーバと、
 - echo3()が作るサーバ
 
の2つがある、ということ。
実際のところ、echo3は、/chart/index.html のクライアント(データの送信元)でもあるんだけど、要求があれば、ポコポコ作り出される、という点ではサーバでもある、という形になっています。
―― という説明を、次に私が頭を抱えた時に、私が思い出せるのかが、不安です



















