Pull to refresh

Первые шаги к онлайн-офису на Linux или как мы портировали под Mono (о сложностях и их преодолении)

Reading time 5 min
Views 36K


Вчера мы выпустили ONLYOFFICE под Linux и спешим поделиться не только новостями, но и полезной информацией для тех, кто, как и мы, 5 лет назад оказался в собственной ловушке под названием «ASP.Net»

Попытки портировать приложение на Unix с использованием проекта Mono мы начали предпринимать еще 4 года назад, однако, долгое время у нас ничего не получалось, поскольку на тот момент Mono сильно отставал по функционалу при портировании с .Net под Windows. В частности, в Mono была сильно урезана поддержка wcf, а также плохо работал asp.net mvc. Впрочем, к счастью разработчиков все эти годы проект Mono активно развивался — добавилась поддержка .Net 4.0 и .Net 4.5, так что весной 2013 мы решили возобновить работу.

Здесь мы расскажем о том, с какими проблемами столкнулись в процессе портирования облачного офиса под Mono, как их решили, что имеем в итоге, и как один инициативный пользователь уже через пару часов после релиза обернул всё в Dockerfile.

Основные сложности при портировании на Mono



1. Работа с файловой системой


Что происходит: сайт не открывается, картинки не отображаются или отображаются некорректно. Сейчас проблема подробно описана на официальном сайте Mono Project.

В чем дело: в Windows прямой и обратный слеш — это одно и тоже, а в Unix — два совершенно разных пути. В Windows пути нечувствительны к регистру, а в Unix — это разные имена.
Как решить проблему:
  • замена всех строк с путями и разделителями директорий в них на работу через класс Path. Использование везде Path.Combilne и Path.DirectorySeparatorChar.
  • проверка всех css и аналогичная корректировка путей для работы под обеими системами.
  • использование в Mono переменной окружения MONO_IOMAP=all для работы под Mono с путями с возможностью игнорирования регистра символов.

2. Незакрывающиеся транзакции


Что происходит: незакрывающиеся транзакции в базе данных MySQL.
В чем дело: к сожалению, так и не выяснили до конца (есть предположения?)
Как решили: добавили параметр в строке подключения AutoEnlist=false

3. Различия в работе xml Mono сериализаторов


Что происходит: различие в xml представлении полей со значением null и исключение в mono сериализаторе при использовании пустых namespace в xml.
Как решили: Убрали wcf сервис модуля «Документы» и заменили на webapi.

4. Утечки памяти


Что происходит: утечка памяти при использовании mod_mono_server для apache2. Например, при вставке новых данных в HttpRuntime.Cache с ключом, который уже есть в кеше, Mono, в отличие от .NET, не освобождает память занятую предыдущими данными.
В чем было дело: все ещё загадка для нас.
Как решили: для решения данной проблемы требуется явно удалять старые данные перед вставкой новых. Мы в свою очередь перешли на nginx, где подобной проблемы не наблюдалось.

5. Исключения типа NullReferenceException


Что происходит: в WCF-сервисе при обращении к членам класса ConfigurationManager возникал NullReferenceException, если ранее мы где-либо перезаписывали свойство HttpContext.Current.
В чем дело: если вручную выставить в не веб-приложении HttpContext.Current, то mono начинает использовать вместо ConfigurationManager — WebConfigurationManager, что приводит к исключениям в не веб-приложении.
Как решили: избавились от установки вручную HttpContext.Current.

6. Несовместимость Microsoft версии и HTTP WCF


В чем дело: HTTP WCF Mono сервис имеет много мелких различий по сравнению с Microsoft версией (например, небольшие различия в xml при сериализации; в mono версии расширения нельзя указать через атрибуты, только через конфигурационный файл; отсутсвует HttpContext.Current, и так далее).
Как решили: переписали HTTP WCF сервис документов на версию, основанную на Web API.

7. Падение SignalR-сервера при нагрузочном тестировании


В чем дело: при обмене сообщениями в чате, встроенном в страницу, мы используем библиотеку ASP.NET SignalR. При портировании ONLYOFFICE под Mono нам хотелось бы и там использовать данную библиотеку. Она поддерживает несколько типов транспортов для передачи данных: websockets, long polling, forever frame, server sent events. Наиболее предпочтительной для нас является технология вебсокетов, которую мы используем в нашей Saas-версии. К сожалению, на данный момент SignalR не позволяет использовать вебсокеты под Mono, поэтому была предпринята попытка в качестве транспорта использовать Long Polling. Но на этапе нагрузочного тестирования SignalR-сервер падал с исключением System.IO.IOException: «Too many open files» — примерно после тысячи подключений клиентов. При последующем изучении проблемы была замечена утечка сокетов на SignalR-сервере после дисконекта клиента, о чем мы сообщили разработчикам SignalR. Надеемся в следующей версии SignalR данная проблема будет решена.
Как решили: другие транспорты не подходят для решения наших задач по разным причинам, поэтому на данный момент для версии под Mono нам пришлось отключить чат, работающий через SignalR.

В общей сложности было внесено несколько сотен измений в проект, однако, в результате нам удалось сделать такую версию, которая при сборке из одних и тех же исходников корректно работает и под Windows, и под Unix с использованием Mono.

Что мы имеем в итоге


Прошло полгода с тех пор, как заработала первая страничка ONLYOFFICE под Mono. Сегодня мы имеем кроссплатформенное решение для управления проектами и документами, ведения базы клиентов, усиленное почтовым агрегатором и другими инструментами для совместной работы.



В качестве защиты авторского права на наш продукт мы выбрали лицензию AGPL v.3, то есть вы можете разворачивать ONLYOFFICE Common для внутренней работы команды, однако, используя исходники в собственном проекте, вы обязаны открыть его код под той же лицензией.

Тренд на Docker


Уже через пару часов после выхода версии, на нашем форуме разработчиков появилось сообщение от инициативного пользователя, который опередил нас и уже успел обернуть всё решение в Dockerfile (за что ему отдельное большое спасибо).

Несмотря на то, что с этой сборкой еще стоит поработать, тренд угадан верно — в ближайшее время мы планируем подготовить ONLYOFFICE Docker-контейнер для каждого языка распространения.

Онлайн-редакторы документов на Linux — Coming Soon


Большая часть бекэнда редакторов документов ONLYOFFICE написана на С++, поэтому перевод приложения под Linux осуществляется иными методами.

Например, недавно мы закончили работу с элементами, отвечающими за конвертацию форматов документов. Основная сложность здесь состоит в том, чтобы избавиться от компонентов ActiveX и ATL.

Чтобы реализовать задуманное, необходимо было осуществить четыре шага:
  • Избавиться от контейнеров ATL (таких как списки, массивы и т.д) и использовать вместо них STL
  • Переписать CString — класс для работы со строками — для других платформ.
  • Избавиться от платформозависимых вызовов API и, где необходимо, использовать сторонние библиотеки (например, написали враппер над библиотекой cURL для закачки картинок, вместо WinInet — части WinAPI для работы с сетью).
  • Уйти от ActiveX и собрать LIB'ы вместо COM-библиотек, а также исполняемые файлы, использующие эти либы.

В ближайшие планы входит разработка десктопных офисных приложений под популярные ОС, поэтому для сборки мы использовали qmake из фреймворка Qt Framework. К тому же IDE QtCreator показалась наиболее удобным вариантом для разработки и отладки кода.

* * *

Если бы мы начинали разработку продукта сегодня, то конечно, обратились бы к ASP.NET vNext, который анонсировали как раз к окончанию процесса портирования ONLYOFFICE (о несправедливый мир разработки!). Впрочем, дело уже сделано, а планы, как всегда, наполеоновские. В следующем году мы выпускаем открытый онлайн-офис под Linux, а значит сможем наконец помериться силами с OpenOffice на их же территории. Впрочем, это уже совсем другая история, о которой мы подробнее расскажем в январе.

А пока что наша команда поздравляет всех с наступающим Новым Годом!
ps. Кто душой уже на каникулах, а телом в офисе, может скоротать часы, посчитав всех пингвинов на фотке (наши сотрудники не в счёт ;)

Tags:
Hubs:
+45
Comments 24
Comments Comments 24

Articles