有没有好的 sql 数据库 driver 推荐, 最好同时支持 mysql 跟 pg?

有问必答Xargin 回复了问题 • 3 人关注 • 2 个回复 • 143 次浏览 • 1 小时前 • 来自相关话题

我用golang重写了2300+star的开源node项目.

开源程序nilman 发表了文章 • 0 个评论 • 30 次浏览 • 3 小时前 • 来自相关话题

我很早前用node写了这开源项目:p2pspider,因为网络流量非常巨大,再加上v8有内存限制,我不得不每隔6小... 查看全部

我很早前用node写了这开源项目:p2pspider,因为网络流量非常巨大,再加上v8有内存限制,我不得不每隔6小时重启,而且cpu占用非常之高,16核的cpu,都差不多占满了,内存也是占用极其高。


在后期维护过程中,因为javascript的原因,发现极其难以维护,让我产生了用静态语言重写的念头。在研究了一些各种主流编程语言,最后选择了golang。 选它主要看中三点:1,语法极其简单;2,goroutine;3,运行速度极其快。


花了十几天左右,就重写完成,一运行,在同样工作效率的情况下,golang版本的p2pspider的综合消耗,远远低于node版,只有node的10%,这很出乎我的意料,毕竟是第一次写golang程序,很可能写得很粗糙。


由于对golang不是很熟,中间踩了很多坑,在此不表了。总之,golang是个很赞的编程语言。

golang中变量回收销毁的一个问题

有问必答cholerae 回复了问题 • 4 人关注 • 3 个回复 • 67 次浏览 • 4 小时前 • 来自相关话题

针对函数的mock测试

有问必答lrita 回复了问题 • 4 人关注 • 3 个回复 • 60 次浏览 • 5 小时前 • 来自相关话题

请问一下json.Unmarshal()为什么一直取不到值?

有问必答明_ 回复了问题 • 2 人关注 • 1 个回复 • 22 次浏览 • 5 小时前 • 来自相关话题

RobotGo v0.47.0 发布, Go 桌面自动化, 移除 libpng 等依赖

开源程序veni 回复了问题 • 2 人关注 • 2 个回复 • 232 次浏览 • 6 小时前 • 来自相关话题

使用base64Captcha Package快速创建golang RESTful图形验证服务

开源程序jjjjerk 发表了文章 • 3 个评论 • 74 次浏览 • 14 小时前 • 来自相关话题

为什么base64图片 for RESTful 服务

  Data URIs 支持大部分浏览器,IE8之后也支持.
  小图片使用base64响应对于RESTful服务来说更便捷

CSS ... 查看全部

为什么base64图片 for RESTful 服务


  Data URIs 支持大部分浏览器,IE8之后也支持.
小图片使用base64响应对于RESTful服务来说更便捷

CSS Image 嵌入base64图片


div.image {
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...);
}

HTML 嵌入base64图片img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA..."


godoc文档


在线Demo Playground Powered by Vuejs+elementUI+Axios


Playground


快速开始


安装golang包


go get -u github.com/mojocn/base64Captcha

使用golang搭建API服务


package main

import (
"encoding/json"
"fmt"
"github.com/mojocn/base64Captcha"
"log"
"net/http"
"strconv"
)

// base64Captcha verify http handler
// golang 比较图像验证码 返回json
func captchaVerifyHandle(w http.ResponseWriter, r *http.Request) {
//接收客户端发送来的请求参数
r.ParseForm()
formData := r.Form
captchaId := formData.Get("captchaId")
captchaDigits := formData.Get("captchaDigits")

//比较图像验证码
verifyResult := base64Captcha.VerifyCaptcha(captchaId, captchaDigits)

//设置json响应
w.Header().Set("Content-Type", "application/json; charset=utf-8")
body := map[string]interface{}{"code": "error", "data": "验证失败", "msg": "captcha failed", "debug": formData}
if verifyResult {
body = map[string]interface{}{"code": "success", "data": "验证通过", "msg": "captcha verified", "debug": formData}
}
json.NewEncoder(w).Encode(body)
}

// base64Captcha create http handler
// 接收idKey字符串 返回base64 Data URIs 图像验证码json
func generateCaptchaHandler(w http.ResponseWriter, r *http.Request) {
//接收客户端发送来的请求参数

r.ParseForm()
formData := r.Form
//图像验证码的idKey 客户端返回.如果使用到传统web服务,idKey服务器生成设置cookie里面
captchaId := formData.Get("captchaId")
//下面的参数都是图像验证码的外观参数,可以不设置条用base64Captcha.GenerateCaptchaPngBase64StringDefault(captchaId)也可以
DotCount, _ := strconv.Atoi(formData.Get("DotCount"))
MaxSkew, _ := strconv.ParseFloat(formData.Get("MaxSkew"), 64)
PngWidth, _ := strconv.Atoi(formData.Get("PngWidth"))
PngHeight, _ := strconv.Atoi(formData.Get("PngHeight"))
DefaultLen, _ := strconv.Atoi(formData.Get("DefaultLen"))

//利用base64Captcha,创建base64图像验证码
base64Png := base64Captcha.GenerateCaptchaPngBase64String(captchaId, PngWidth, PngHeight, DotCount, DefaultLen, MaxSkew)
//你也可以是用默认参数 生成图像验证码
//base64Png := captcha.GenerateCaptchaPngBase64StringDefault(captchaId)

//设置json响应

w.Header().Set("Content-Type", "application/json; charset=utf-8")
body := map[string]interface{}{"code": 1, "data": base64Png, "msg": "success", "debug": formData}
json.NewEncoder(w).Encode(body)
}

//启动golang net/http 服务器
func main() {
//serve Vuejs+ElementUI+Axios Web Application
http.Handle("/", http.FileServer(http.Dir("./static")))
//api for create captcha
http.HandleFunc("/api/getCaptcha", generateCaptchaHandler)
//api for verify captcha
http.HandleFunc("/api/verifyCaptcha", captchaVerifyHandle)

fmt.Println("Server is at localhost:777")
if err := http.ListenAndServe(":777", nil); err != nil {
log.Fatal(err)
}
}

base64Captcha package 主要方法



  • 自定参数返回验证码base64png 返回base64 Data URIs
    func GenerateCaptchaPngBase64String(identifier string, pngWidth, pngHeight, DotCount, digitsLen int, maxSkew float64) string


  • 使用默认配置 返回base64 Data URIs,默认参数 width=240 height=70 dot-count=20 digits-len=6 skew-factor=0.7
    func GenerateCaptchaPngBase64StringDefault(identifier string) string



  • 比较返回的数字图像验证码的正确性
    func VerifyCaptcha(identifier, digits string) bool

  • 参数随机的idKey
    func RandomId() string


  • 更详细文档请查看godoc


    运行demo代码


    cd $GOPATH/src/github.com/mojocn/captcha/examples
    go run main.go


    访问 http://localhost:777


    golang-demo nginx 反向代理配置 captcha.mojotv.cn.config


    server {
    listen 80;
    server_name captcha.mojotv.cn;
    charset utf-8;

    location / {
    try_files /_not_exists_ @backend;
    }
    location @backend {
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:777;
    }
    access_log /home/wwwlogs/captcha.mojotv.cn.log;
    }



如果觉得这教程有用请访问GitHub 提Issue Star Fork

beego rest ful 请求参数为JSON怎么获取

有问必答madmen 回复了问题 • 4 人关注 • 3 个回复 • 987 次浏览 • 16 小时前 • 来自相关话题

GOCN每日新闻(2017-12-13)

回复

每日新闻yulibaozi 发起了问题 • 1 人关注 • 0 个回复 • 245 次浏览 • 17 小时前 • 来自相关话题

go汇编入门

文章分享lrita 发表了文章 • 0 个评论 • 112 次浏览 • 1 天前 • 来自相关话题

golang echo 代码详解之模版篇

技术讨论Laily 发表了文章 • 0 个评论 • 82 次浏览 • 1 天前 • 来自相关话题

在 echo 里使用模版则必须先注册一个,如果不注册就会报出下面这样的错误

{"time":"2017-12-12T23:... 			查看全部
					

在 echo 里使用模版则必须先注册一个,如果不注册就会报出下面这样的错误


{"time":"2017-12-12T23:03:57.939138716+08:00","level":"ERROR","prefix":"echo","file":"echo.go","line":"284","message":"Renderer not registered"}

注册就是给 echo.Renderer 赋值。


echo 的 Renderer 属性是一个接口


Renderer interface {
Render(io.Writer, string, interface{}, Context) error
}

一、使用标准库模版


echo 的文档给出了使用官方模版注册的方式


// 实现 Renderer 接口
type Template struct {
templates *template.Template
}

func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
// 处理 view 目录下的文件生成对应的模版
// 关于 ExecuteTemplate 和 ParseGlob 方法可以查看
// https://wizardforcel.gitbooks. ... plate
t := &Template{
templates: template.Must(template.ParseGlob("public/views/*.html")),
}
// 赋值
e.Renderer = t

二、使用 pongo2


gopkg.in/flosch/pongo2.v3 是一个很不错的模版引擎,很多时候会选择它来渲染模版。


首先还是实现 Renderer 接口


type Template struct {
// 这里使用一个 map 来存储预处理了的模版
tmplMap map[string]*pongo2.Template
}

func (t *Template) Render(w io.Writer, templateName string, data interface{}, c echo.Context) error {
// 这里根据传来的 name 从 tmplMap 里查找模版来渲染
// 注意 ExcuteWriter 的参数必须是 map[string]interface{} 的
dataMap := data.(map[string]interface{})
template, exist := t.tmplMap[templateName]
if !exist {
return errors.New("template " + templateName + " not found")
}
return template.ExecuteWriter(dataMap, w)
}

然后预编译模版


// 读取目录下的文件预处理
func preCompile(dir string) *Template {
tmplMap := make(map[string]*pongo2.Template)

dirPath := filepath.Dir(dir)
fileInfos, _ := ioutil.ReadDir(dirPath)

for _, fileInfo := range fileInfos {
t, err := pongo2.FromFile(path.Join(dir, fileInfo.Name()))
if err != nil {
log.Fatalf("\"%s\": %v", fileInfo.Name(), err)
}
tmplMap[strings.Replace(fileInfo.Name(), path.Ext(fileInfo.Name()), "", -1)] = t

}

return &Template{tmplMap}
}

最后赋值


func NewTemplates(dir string) *Template {
return preCompile(dir)
}

t := NewTemplates("./views/")
e.Renderer = t

这样自定义的 renderer 就算完成了。


原文地址:laily.net

go超级时间轮timewheel(一路向前)github.com/anjieych/timewheel

开源程序Anjie 发表了文章 • 0 个评论 • 118 次浏览 • 1 天前 • 来自相关话题

go超级时间轮timewheel(一路向前)github.com/anjieych/timewheel

有传统时间轮的影子,但又超出传统时间轮:

  1. 非“盘/环”形结构: 一路向前,永... 查看全部

go超级时间轮timewheel(一路向前)github.com/anjieych/timewheel


有传统时间轮的影子,但又超出传统时间轮:



  1. 非“盘/环”形结构:
    一路向前,永不回头,每tick一次,移除一个slot;每个slot中的entity 触发OnExpired来处理到期(或过期)事件;

  2. 超级时间轮:
    他是一个轮或者轮的集合,因为他可以同时处理不同实现了Entity的业务,每个业务有各自OnExpired定义,只要可以遵循相同的时间刻度Interval就可以放入同一个轮来统一计时触发。
    最后,优点或缺点可以作者交流。


[========]


package main

import (
"fmt"
"github.com/anjieych/timewheel"
"time"
)

func main() {
tw := timewheel.NewTimewheel("tw-example", time.Second)
tw.Start()
tick := time.NewTicker(3 * time.Second)
for {
d := &Data{
eid: time.Now().UnixNano(),
data: <-tick.C,
}
d.SetSlotId(tw.Add(d, 5*time.Second))
}
}
// Data must implements timewheel.Entity
type Data struct {
eid int64
slotId int
data interface{}
}

func (d *Data) SetEId(eId int64) {
d.eid = eId
}
func (d *Data) GetEId() (eId int64) {
return d.eid
}
func (d *Data) SetSlotId(slotId int) {
d.slotId = slotId
}
func (d *Data) GetSlotId() (slotId int) {
return d.slotId
}
func (d *Data) OnExpired() {
fmt.Printf("%s\t OnExpired :{slotId: %d\t,eid: %d\t,data: %s}\n", time.Now(), d.GetSlotId(), d.GetEId(), d.data)
}

GOCN每日新闻(2017-12-12)

回复

每日新闻傅小黑 发起了问题 • 1 人关注 • 0 个回复 • 307 次浏览 • 1 天前 • 来自相关话题

LiteIDE X33.1 发布,Go 语言开发工具

开源程序visualfc 发表了文章 • 2 个评论 • 150 次浏览 • 1 天前 • 来自相关话题

Go 语言开发工具 LiteIDE X33.1 正式发布。 新版本对菜单进行调整和规范,新增了工具菜单,编辑菜单保持可见,重命名了部分工具窗口。 修复了编辑器内查找功能的全文替换错误, 对快速打开文件操作 ( ctrl+p / command+p ) 改... 查看全部

Go 语言开发工具 LiteIDE X33.1 正式发布。 新版本对菜单进行调整和规范,新增了工具菜单,编辑菜单保持可见,重命名了部分工具窗口。 修复了编辑器内查找功能的全文替换错误, 对快速打开文件操作 ( ctrl+p / command+p ) 改用线程方式重新实现,新增了快速打开命令功能 ( ctrl+shift+p / command+shift+p ),集成了 gomodifytags 并提供GUI界面实现对结构体 Tags 的快速增删功能。


LiteIDE X33.1 使用 go1.10beta1 编译, 支持 Go1.9 / Go1.10beta1 或者更低的 Go 版本。


Links





2017.12.12 Ver X33.1



  • LiteEditor

    • support quick open command

    • support gomodifytags

    • fix libpng warning on qt5 build


  • LiteApp

    • add tools menu for quick open actions

    • standard and rename tool window title

    • enable edit menu anytime, fix edit menu disable on editor lost focus.

    • fix editor load large file bad_alloc recover


  • LiteEnv

    • add select env to tools menu


  • LiteEditor

    • check and not open large file

    • fix edit hide edit sub menu 'setup' on macos


  • LiteFind

    • fix find editor replace all wrap around* GolangEdit

    • Integrated gomodifytags and gui tools support gomodifytags all options


  • QuickOpen

    • add quick open command action (ctrl+shift+p/command+shift+p)

    • quickopenfiles use thread for fast and cancel

    • fix quickopenfile cancel loading for esc or liteapp quit


数组的指针问题

有问必答Mr_Wings 回复了问题 • 2 人关注 • 2 个回复 • 151 次浏览 • 2 天前 • 来自相关话题