Golang Go语言限制goroutine数量的方法

package main 

import "time" 

func work(ch chan int) {  //工作方法
    //做事
    <- ch  //完事后在 ch里面抽一个数。
} 

func main() {
    ch := make(chan int, 100)  //限制100个goroutine
    for i := 0; ; i++ {
        ch <- 1              //如果当有已经有100个goroutine在工作,那么此事就会堵塞直到有goroutine工作完
        go work(ch)
    }
}

Golang Go语言发送邮件的方法

传统的思路

package main

import (
        "log"
        "smtp"
)

func main() {
        // Set up authentication information.
        auth := smtp.PlainAuth(
                "",
                "user@example.com",
                "password",
                "mail.example.com",
        )
        // Connect to the server, authenticate, set the sender and recipient,
        // and send the email all in one step.
        err := smtp.SendMail(
                "mail.example.com:25",
                auth,
                "sender@example.org",
                []string{"recipient@example.net"},
                []byte("This is the email body."),
        )
        if err != nil {
                log.Fatal(err)
        }
}

Go语言流式操作方法来发邮件

package main

import (
        "log"
        "smtp"
)

func main() {
        // Set up authentication information.
        auth := smtp.PlainAuth(
                "",
                "user@example.com",
                "password",
                "mail.example.com",
        )
        // Connect to the remote SMTP server.
        c, err := smtp.Dial("mail.example.com:25")
        if err != nil {
                log.Fatal(err)
        }
        err = c.Auth(auth)
        if err != nil {
        	log.Fatal(err)
        }
        // Set the sender and recipient.
        c.Mail("sender@example.org")
        c.Rcpt("recipient@example.net")
        // Send the email body.
        wc, err := c.Data()
        if err != nil {
                log.Fatal(err)
        }
        defer wc.Close()
        if _, err = wc.Write([]byte("This is the email body.")); err != nil {
                log.Fatal(err)
        }
}


英文来源
,做过一点点修改。

给网站添加Google+1按钮的方法

网站为何要添加一个新的按钮?

按钮多了,可能有的人会觉得烦了,那么Google+1加了有何用呢?目前情况是:更多人给你的网站+1,那么就有更多的可能,更多的人搜索的时候在Google搜索结果里面显示他们社交圈朋友的推荐内容,而你的网站就是被推荐的条目。

怎么给网站添加Google+1按钮?

在网页 head 区放置这段js代码


然后在要放Google+1按钮的地方放入如下代码:


默认情况下使用的按钮大小是 24px的。而且被推荐的网址是当前网页地址。如果要改变这两个东西需要设置参数。

Google+1按钮参数说明

按钮大小包括四种:small 15px大小 medium 20px大小 standard 24px大小 tall 60px大小。
比如要设置为 20px大小的 medium。则代码为


推荐的网址:写在 href参数里面,比如要推荐的网址为 http://kejibo.com则代码为


设置是否显示已经被推荐的次数:参数为 count,如果显示(默认情况):属性为 true,如果不想显示就设置为 false如


Golang Go语言结构体中匿名字段暴露方法的优先级

Go语言的结构体中可以包含匿名的字段,比如:

struct {
	T1        // 字段名自动为 T1
	*T2       // 字段名自动为 T2
	P.T3      // 字段名自动为 T3
	*P.T4     // 字段名自动为 T4
	x, y int  // 非匿名字段 x , y
}

如果结构体 S,包含一个匿名字段 T,那么这个结构体 S 就有了 T的方法。
如果包含的匿名字段为 *T,那么这个结构体 S 就有了 *T 的方法。
如果S包含的匿名字段为 T或*T,那么 *S就有了 *T的方法。

比如

type gzipResponseWriter struct {
    io.Writer
}

因为 io.Writer里有 Write方法,所以 gzipResponseWriter 也有了 Write方法

var g gzipResponseWriter
g.Write(数据)

此处的 g.Write 就相当于 g.Writer.Write(数据)。

那么如果两个匿名字段都有同一个方法的时候,会怎么样呢?

type gzipResponseWriter struct {
    io.Writer
    http.ResponseWriter
}

io.Writer这个接口已经有 Write方法了,http.ResponseWriter 同样有 Write方法。那么对 g.Write写的时候,到底调用哪个呢?是 g.Writer.Write 还是 g.ResponseWriter.Write呢?你不知道程序也不知道,如果编译就出现“Write模糊不清”的错误。

怎么解决这个问题?

其一:就是重写 gzipResponseWriter的 Write方法,指明要写到哪一方。

func (w gzipResponseWriter) Write(b []byte) (int, os.Error) {
    return w.Writer.Write(b)
}

上面这里就是指定使用 io.Writer里面的 Write方法。

其二:使用匿名字段暴露方法优先级来确定重复方法的时候使用哪一个方法,原则就是【简单优先】。所以我们这里把 http.ResponseWriter弄复杂一点,使用另一个结构体先包裹一次。

type responseWriter struct {
    http.ResponseWriter
}

然后再在 gzipResponseWriter里面插入这个结构体

type gzipResponseWriter struct {
	io.Writer
	responseWriter
}

这样就是 io.Writer的方法是会优先暴露出来的。这样就省去了上面那样的麻烦,而且当有多个重复方法的时候,还得一个一个来改写。记得使用 gzipResponseWriter 的时候原来的 类型为 http.ResponseWriter 的对象比如 w,要用 responseWriter{w},包装一下就可以使用到 gzipResponseWriter里面了。


参考英文及评论内容

Golang Go语言中的try … except …统一的异常处理

写python的时候,有时候懒得一个一个错误去分别处理,直接使用一个整体来try catch来捕获所有异常。如:

try:
	one()
	two()
	three()
except:
	处理异常

Go中的实现方式:

func main() {
        defer func() {
        	if e, ok := recover(); ok {
			println(e.String())  //打印出错误
		}
        }()
        one()
        two()
        three()
        ...
}

这样one two three任何一个执行中的异常都会被前面的这个闭包函数捕获。

Golang Go语言实现Virtualhost虚拟主机效果

如果是单个域名,使用没啥好说的一个 http.HandleFunc 来给这个域名注册URL规则就行了。如果是多个域名呢?因为不同的域名就会有不同的规则,所以得分别注册URL规则。当然你也可以分开到另一个go文件中来管理。这里只说同时来管理的情况。

package main

import (
    "http"
)

func hf1(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("hello world from host1"))
}

func hf2(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("hello world from host2"))
}

func main() {
    sm1 := http.NewServeMux()
    sm2 := http.NewServeMux()
    sm1.HandleFunc("/", hf1)
    sm2.HandleFunc("/", hf2)
    http.Handle("www.kejibo1.com/", sm1)
    http.Handle("www.kejibo2.com/", sm2)
    http.ListenAndServe(":80", nil)  //注册到默认的 DefaultServeMux上面,来管理所有域名
}

如果要增加域名规则就分别添加 sm1.HandleFunc(“/”, hf1) 或 sm2.HandleFunc(“/”, hf2) 这样注册方法。

你可能会怀疑注册这样的域名方法,会不会 www.kejibo.com/www.kejibo1.com/ 也会被注册到了 sm1上面呢?通过测试可以发现,并不会。

Golang Go语言简单的文件服务器

package main

import (
    "http"
)

func main() {
    h := http.FileServer(".", "/google")
    http.ListenAndServe(":8888", h)
}

http.FileServer的第一个参数为提供服务的目录,第二参数为前缀名,一般情况下为空就可以。如果你想 http://youserver/prefix/ 这种形式访问到你所提供服务的目录就要把这个参数设置为 /prefix

PPPOE宽带连接或ADSL连接下使用Chrome Proxy Switchy

社区使用的网络突然从DHCP网转成PPPOE拔号网,突然发现Proxy Switchy不能用了。还以为是墙升级了。不过搜一下发现是宽带连接的问题。

修改宽带连接的名称,为英文或数字。

进入 Proxy Switchy 设置,进【Network】面板,选择【Proxy For VPN/Dial-up】,选择刚刚修改了名称的宽带连接。

保存设置。

重启一下电脑(必须的。)。

Facebook秘密雇佣公关公司中伤Google被曝光(邮件)

google-facebook.jpg

Facebook这次真的玩大了,他们秘密雇佣公关公司Burson Marsteller帮助其在各大著名媒体上发表中伤Google的文章的事情被曝光了。

此事的曝光还源于Burson Mersteller公司的一次大意,他们不小心找了一个不太那么愿意助人为恶的博客人去写一篇关于Google侵犯别人隐私的文章。该博客人不但没有写下这样一篇文章,还直接把Burson公司发给他的邮件曝光了出来。


点此
可查看邮件原文。

公司之间的竞争是常有的事,Facebook这次确实是走得太远了,连不作恶的Google他们都去伤害,我们可以想象其在背后不知到还做了多少伤人的事。

文章来自
36氪

用Golang Go语言写个http代理服务器

Go的http包封装的实在很BT,几十行代码就能写个http代理服务器。支持get,post,支持cookie,支持gzip。对了需要使用最新的源码编译,不然会有BUG。自己hg 下载源码编译一下才行,最新的一个BUG刚刚被修正。不多说直接上代码。

package main

import (
    "http"
    "log"
    "os"
    "io/ioutil"
)

func handler(w http.ResponseWriter, r *http.Request) {
    resp, err := http.DefaultClient.Do(r)
    defer resp.Body.Close()
    if err != nil { panic(err) }
    for k, v := range resp.Header {
        for _, vv := range v {
            w.Header().Add(k, vv)
        }
    }
    for _, c := range resp.SetCookie {
        w.Header().Add("Set-Cookie", c.Raw)
    }
    w.WriteHeader(resp.StatusCode)
    result, err := ioutil.ReadAll(resp.Body)
    if err != nil && err != os.EOF { panic(err) }
    w.Write(result)
}

func main() {
    http.HandleFunc("/", handler)
    log.Println("Start serving on port 8888")
    http.ListenAndServe(":8888", nil)
    os.Exit(0)
}

原创文章转载请注明出明出处,

http://kejibo.com/golang-http-proxy-server/