Лично мне это чем-то напомнило решения типа Heroku. У них есть входная точка, потом идет роутер, который посылает запросы к worker'ам, а ими может быть все, что угодно — nodejs, go, ruby, python.
К worker'ам же подключаются различные плагины в виде БД, поиска (elastichsearch), аналитики, отправки писем и т.д., сами эти сервисы работают в «облаках».
Причем так как это все работает в основном в Amazon датацентрах (и Heroku, и плагины), то связь между системами идет по локальной гигабитной сети и задержки минимальны.
Хм, если я правильно вас понял, то pusher.com и pubnub.com как раз для этого и существуют. Вписываешь appKey, подписываешся на канал и ждешь сообщений.
Конечно там нет протокола обмена изображениями, эмоций и т.д., но это не сложно делается и получается более гибко, когда сервис передает лишь сообщения (можно сделать свой простой протокол, например, на основе JSON).
Оба сервиса поддерживают WebSocket, online-статусы (кто в сети на канале). На канал может подписатся как 1 человек (приватная комната), так и много (групповой чат).
В общем то они заявляют, что их сервисы подходят не только для чатов и приложений в реальном времени, но даже для мультиплеерных игр.
В Go лично мне еще нравится автоформатирование исходного кода с помощью утилиты Gofmt (особенно когда редактор запускает форматирование кода после каждого сохранения файла, например SublimeText с расширением GoSublime).
В Go чаще всего используется не один большой фреймворк, а комбинация нескольких пакетов.
Но как правильно сказали в Braintree, иногда кажется что в Go надо постоянно переделывать простые вещи, поэтому мы создали для этого отдельный проект на github для того, чтобы не повторять рутинные операции, например по декодированию Json из тела ответа, ошибок API, http клиент, валидации и т.д. (он сейчас просто сборка функций, можно сказать в альфа-версии, поэтому ссылку не привожу — можете посмотреть на github, если интересно, по моему имени пользователя на хабре)
Например, Martini очень простой для понимания пакет, особенно удобно его Dependency Injection (правда с ним нужно быть аккуратнее, потому что при компилировании не будут выводится никакие ошибки из-за того, что зависимости передаются динамически — например передан пустой указатель).
В Go шаблоны (templates) по-моему отличные из коробки. Очень быстрые и легкие в использовании.
В Martini очень просто создавать middleware: мы используем их, например, для подготовки структуры логов и для переменных уровня запросов вот так:
Где ReqValues — это struct со значениями глобальных оповещений (alert'ов), пользователя (берется из Redis в отдельном middleware) и т.д.
Так как map передается всегда как указатель, но можно создать несколько простых функций, которые будут заполнять template.FuncMap какими-нибудь функциями-помощниками, как в Rails. Например:
func (s *Sprockets) SetFuncMap(funcMap template.FuncMap) {
funcMap["asset_path"] = s.AssetPath
}
Тестирование Martini хитрее. Можно сделать простую функцию App(), которая инициализирует все middleware, создает пути и возвращает *martini.Martini.
func App() *martini.Martini {
m := martini.New()
// Setup default middleware
m.Use(martini.Recovery())
r := martini.NewRouter()
r.NotFound(func() (int, string) {
return 404, wutapi.Error404()
})
// Add the router action
m.Action(r.Handle)
return m
}
После чего в тестах можно вызывать ServeHTTP и смотреть результат. Например:
func Test_Applications_GetAll(t *testing.T) {
res := httptest.NewRecorder()
req := makeReq("GET", "/v1/oauth2/applications")
App().ServeHTTP(res, req)
assert.Equal(t, res.Code, 200, "they should be equal")
}
Этот подход удобен тем, что почти все пакеты используют стандартную библиотеку (к слову, очень хорошо и грамотно сделаную, можно даже сказать потрясающе, но у меня мало опыта сравнения например с Java или C++ — мне лично стандартная библиотека Go очень понравилась), поэтому можно заменять и дополнять пакеты как душе угодно и как лучше для проекта.
Проблемы взаимосвязи между пакетами решатся на уровне компиляции.
Первый раз только сложновато было придумать структуру проекта и разобратся что и где использовать, а потом это кажется уже натуральным.
К worker'ам же подключаются различные плагины в виде БД, поиска (elastichsearch), аналитики, отправки писем и т.д., сами эти сервисы работают в «облаках».
Причем так как это все работает в основном в Amazon датацентрах (и Heroku, и плагины), то связь между системами идет по локальной гигабитной сети и задержки минимальны.
Конечно там нет протокола обмена изображениями, эмоций и т.д., но это не сложно делается и получается более гибко, когда сервис передает лишь сообщения (можно сделать свой простой протокол, например, на основе JSON).
Оба сервиса поддерживают WebSocket, online-статусы (кто в сети на канале). На канал может подписатся как 1 человек (приватная комната), так и много (групповой чат).
В общем то они заявляют, что их сервисы подходят не только для чатов и приложений в реальном времени, но даже для мультиплеерных игр.
Так удобно, когда все в одном стиле.
Но как правильно сказали в Braintree, иногда кажется что в Go надо постоянно переделывать простые вещи, поэтому мы создали для этого отдельный проект на github для того, чтобы не повторять рутинные операции, например по декодированию Json из тела ответа, ошибок API, http клиент, валидации и т.д. (он сейчас просто сборка функций, можно сказать в альфа-версии, поэтому ссылку не привожу — можете посмотреть на github, если интересно, по моему имени пользователя на хабре)
Например, Martini очень простой для понимания пакет, особенно удобно его Dependency Injection (правда с ним нужно быть аккуратнее, потому что при компилировании не будут выводится никакие ошибки из-за того, что зависимости передаются динамически — например передан пустой указатель).
В Go шаблоны (templates) по-моему отличные из коробки. Очень быстрые и легкие в использовании.
В Martini очень просто создавать middleware: мы используем их, например, для подготовки структуры логов и для переменных уровня запросов вот так:
Где ReqValues — это struct со значениями глобальных оповещений (alert'ов), пользователя (берется из Redis в отдельном middleware) и т.д.
Так как map передается всегда как указатель, но можно создать несколько простых функций, которые будут заполнять template.FuncMap какими-нибудь функциями-помощниками, как в Rails. Например:
Тестирование Martini хитрее. Можно сделать простую функцию App(), которая инициализирует все middleware, создает пути и возвращает *martini.Martini.
После чего в тестах можно вызывать ServeHTTP и смотреть результат. Например:
Этот подход удобен тем, что почти все пакеты используют стандартную библиотеку (к слову, очень хорошо и грамотно сделаную, можно даже сказать потрясающе, но у меня мало опыта сравнения например с Java или C++ — мне лично стандартная библиотека Go очень понравилась), поэтому можно заменять и дополнять пакеты как душе угодно и как лучше для проекта.
Проблемы взаимосвязи между пакетами решатся на уровне компиляции.
Первый раз только сложновато было придумать структуру проекта и разобратся что и где использовать, а потом это кажется уже натуральным.