작년에 미뤄뒀던 Go를 다시 보고 있다.
동기부여를 위해 회사 안내 홈페이지를 망할 일도 없고 비용이 안드는 곳으로 옮기고 싶은 생각이 있었는데
Google App Engine(이하 GAE)정도면 뭐 망할 일이 없겠지 싶다.
Google Apps 처럼 유료화해도 먼저 만들어 놓은 서비스/계정은 안건드니까 먼저 침이라도 발라놓아야지.
개발환경 세팅은 간단했다.
Download 에서 package 를 받고 설치한 다음
goide를 쓰고 싶었으나 아직 완성도 문제가 있어서 sublime을 사용하기로 결정.
http://wbond.net/sublime_packages/package_control/installation 는 전에 설치해놓았다.
그저 sublime을 띄운 상태에서 ctrl+` (OS X에서도 ctrl+` 임)을 누르면 나타나는 하단 콘솔창에
그 다음 sublime용 golang plugin인 GoSublime을 추가
데모 동영상을 보면서 사용법을 간단하게 알아보면
0:11즈음에 나오는 package 삽입 기능은 ctrl(cmd)+. , ctrl(cmd)+p 사용
package 삽입 뿐만이 아니라 삭제도 되어서 안쓰는 package가 있는 경우 컴파일 오류를 뿜어내는 go 에선 아주 편리.
ctrl(cmd)+b(0:22에 나옴)하면 go shell을 사용.
ctrl(cmd)+. , ctrl(cmd)+. (0:28 즈음) 연타하고 share 하면 play.golang.org 에 code snippet 올리고 URL까지 뽑아줌. 재밌는 기능.
실행시엔 그냥 ctrl(cmd)+. , ctrl(cmd)+R 하면 된다. (ctrl 혹은 cmd 키를 누른채로 .과 R을 연속해서 입력)
생각보다 정적 웹서버를 구현하는 건 어이없을 정도로 간단.
package main
import (
"log"
"net/http"
)
func main() {
log.Fatal(http.ListenAndServe(":3000", http.FileServer(http.Dir("./public"))))
}
:3000포트로 들어온 http Request를 FileServer를 통해 public 디렉토리 하위에 있는 문서랑 연결하는 방식이다.
node.js와 coffeescript로 twitter 포스팅용 simpleHTTPServer 소스(https://gist.github.com/4414368)를 올린적이 있는데
go도 역시 만만치 않다. 물론 실제로 FileServer를 풀어 헤쳐서 구현하려면 손이 더 타겠지만 일단은 간단하다. (하지만, node.js 의 방식이 더 누군가에게 설명하거나 이야기 하긴 더 좋다)
다음은 GAE Go SDK를 설치한다.
압축파일(https://developers.google.com/appengine/downloads)을 풀고
적당히 google_appengine 을 이동한뒤 PATH를 잡아준다.
https://developers.google.com/appengine/docs/go/gettingstarted/devenvironment 참조
자 이제 준비는 끝났다.
GAE용 어플리케이션을 만드는게 목적이므로 main 대신 init 으로 변경하자.
근데 문제가 있다.
http.ListenAndServer를 이미 GAE GO 에서 사용하고 있으므로
http.HandleFunc 를 처리해 줘야한다.
이런 식으로 코드를 짜보았다. node용 simpleHTTPServer 와 비슷하게.
package server
import (
"appengine"
"fmt"
"io/ioutil"
"net/http"
)
func init() {
http.HandleFunc("/", handler)
}
func handler(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
path := r.URL.Path
if path == "/" {
path = "/index.html"
}
file, err := ioutil.ReadFile("./public" + path)
if err != nil {
file, err = ioutil.ReadFile("./public/404.html")
c.Infof("404:Requested URL Not Found: %v", r.URL.Path)
}
fmt.Fprint(w, string(file))
}
이렇게 해도 되나 참내;;
동기부여를 위해 회사 안내 홈페이지를 망할 일도 없고 비용이 안드는 곳으로 옮기고 싶은 생각이 있었는데
Google App Engine(이하 GAE)정도면 뭐 망할 일이 없겠지 싶다.
Google Apps 처럼 유료화해도 먼저 만들어 놓은 서비스/계정은 안건드니까 먼저 침이라도 발라놓아야지.
개발환경 세팅은 간단했다.
Download 에서 package 를 받고 설치한 다음
goide를 쓰고 싶었으나 아직 완성도 문제가 있어서 sublime을 사용하기로 결정.
http://wbond.net/sublime_packages/package_control/installation 는 전에 설치해놓았다.
그저 sublime을 띄운 상태에서 ctrl+` (OS X에서도 ctrl+` 임)을 누르면 나타나는 하단 콘솔창에
import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'요 내용을 붙여넣으면 끝.
그 다음 sublime용 golang plugin인 GoSublime을 추가
데모 동영상을 보면서 사용법을 간단하게 알아보면
0:11즈음에 나오는 package 삽입 기능은 ctrl(cmd)+. , ctrl(cmd)+p 사용
package 삽입 뿐만이 아니라 삭제도 되어서 안쓰는 package가 있는 경우 컴파일 오류를 뿜어내는 go 에선 아주 편리.
ctrl(cmd)+b(0:22에 나옴)하면 go shell을 사용.
ctrl(cmd)+. , ctrl(cmd)+. (0:28 즈음) 연타하고 share 하면 play.golang.org 에 code snippet 올리고 URL까지 뽑아줌. 재밌는 기능.
실행시엔 그냥 ctrl(cmd)+. , ctrl(cmd)+R 하면 된다. (ctrl 혹은 cmd 키를 누른채로 .과 R을 연속해서 입력)
생각보다 정적 웹서버를 구현하는 건 어이없을 정도로 간단.
package main
import (
"log"
"net/http"
)
func main() {
log.Fatal(http.ListenAndServe(":3000", http.FileServer(http.Dir("./public"))))
}
이게 전부다. 진짜다;
:3000포트로 들어온 http Request를 FileServer를 통해 public 디렉토리 하위에 있는 문서랑 연결하는 방식이다.
node.js와 coffeescript로 twitter 포스팅용 simpleHTTPServer 소스(https://gist.github.com/4414368)를 올린적이 있는데
go도 역시 만만치 않다. 물론 실제로 FileServer를 풀어 헤쳐서 구현하려면 손이 더 타겠지만 일단은 간단하다. (하지만, node.js 의 방식이 더 누군가에게 설명하거나 이야기 하긴 더 좋다)
다음은 GAE Go SDK를 설치한다.
압축파일(https://developers.google.com/appengine/downloads)을 풀고
적당히 google_appengine 을 이동한뒤 PATH를 잡아준다.
https://developers.google.com/appengine/docs/go/gettingstarted/devenvironment 참조
자 이제 준비는 끝났다.
GAE용 어플리케이션을 만드는게 목적이므로 main 대신 init 으로 변경하자.
근데 문제가 있다.
http.ListenAndServer를 이미 GAE GO 에서 사용하고 있으므로
http.HandleFunc 를 처리해 줘야한다.
이런 식으로 코드를 짜보았다. node용 simpleHTTPServer 와 비슷하게.
package server
import (
"appengine"
"fmt"
"io/ioutil"
"net/http"
)
func init() {
http.HandleFunc("/", handler)
}
func handler(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
path := r.URL.Path
if path == "/" {
path = "/index.html"
}
file, err := ioutil.ReadFile("./public" + path)
if err != nil {
file, err = ioutil.ReadFile("./public/404.html")
c.Infof("404:Requested URL Not Found: %v", r.URL.Path)
}
fmt.Fprint(w, string(file))
}
이렇게 해도 되나 참내;;
디렉토리 구조는 아래와 같이
home/
app.yaml
server/
server.go
public/
index.html
404.html
....
작동이 정상적으로 되는 걸 확인하면 등록하자. 경로로 r.RequestURI를 사용했더니 로컬에선 되는데 서버에서 문제가 있음. 삽질하지말고 r.URL.Path 쓰자.
https://appengine.google.com 에서 어플리케이션 명을 등록하고 그 이름으로 app.yaml 파일을 수정한다.
application: <application name>
version: 1
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
여기까지 하고
appcfg.py update .
를 사용하여 서버에 올리자. 올라가는 속도가 썩 빠르지는 않다.
Python으로 할껄 괜히 go로 한다고 삽질한 듯도 싶고.
그래도 잘 올라가니까 좋네.ㅎ
http.HandleFunc 대신 http.Handle을 쓰고 http.FileServer를 연결해도 되겠구나.
답글삭제package server
import (
"net/http"
)
func init() {
http.Handle("/", http.FileServer(http.Dir("./public")))
}
무쟈게 간단하네;;;