У меня есть существующая библиотека, написанная на C #, которая оборачивает гораздо более низкоуровневый TCP / IP API и предоставляет сообщения, поступающие по проводам с сервера (собственный двоичный протокол), как события .NET.Я также предоставляю вызовы методов для объекта, который обрабатывает сложности маршалинга удобных типов .NET (например, System.DateTime) вплоть до двоичных кодировок и структур фиксированной длины, которые требуются API (для исходящих сообщений на сервер).Существует немало существующих приложений (как внутренних, так и используемых третьими лицами), построенных поверх этой библиотеки .NET.
Недавно к нам обратился человек, который не хочет делать вселегкая работа по абстрагированию самого TCP / IP, но их среда строго не Windows (я полагаю, * nix, но я не уверен на 100%), и они предположили, что их идеал будет чем-то вызываемым из Java.
Каков наилучший способ удовлетворить их требования, без необходимости:
- Портировать код на Java сейчас (включая неуправляемую DLL, которую мы в настоящее время используем для распаковки P / Invoke)
- Нужно поддерживать две отдельные кодовые базы, идущие вперед (т.е. дважды вносить одинаковые исправления ошибок и улучшения возможностей)
Одна вещь, которую я рассмотрел, - переписать большую частьОсновные функциональные возможности TCP / IP - однажды во что-то более кросс-платформенное (C / C ++), а затем измените мою библиотеку .NET на тонкий слой поверх этого (P / Invoke?), а затемПовторите также тонкий Java-слой поверх него (JNI?).
Плюсы:
- В основном я пишу вещи только один раз.
Минусы:
- Большая часть кода теперь будет неуправляемой - не конец света, но не идеальный с точки зрения производительности (для меня).
- Большевремя разработки (нельзя переносить код сокетов C # на C / C ++ так же быстро, как просто перенос на Java) [Насколько это верно?]
- На этом этапе основной API в основном упакован, а библиотека оченьстабильный, так что, вероятно, не так уж много новых разработок - может быть не так уж и плохо просто перенести текущий код на Java, а затем придется периодически исправлять ошибки или выставлять новые поля дважды в будущем.
- Потенциальная нестабильность для моих существующих клиентских приложений, в то время как версия, на которой они работают, резко меняется под ними.(Вдобавок ко всему, я могу вспомнить проблемы с 32/64 битами, проблемы с порядком байтов и общие ошибки, которые могут возникнуть во время порта и т. Д.)
Еще один вариант, который я кратко рассмотрелкаким-то образом настраивает Mono до Java, чтобы я мог использовать весь существующий код C #, который у меня уже есть.Я не слишком осведомлен о том, насколько гладким будет опыт разработчика для разработчиков Java, которые должны его использовать.Я почти уверен, что большая часть кода должна без проблем работать под Mono (за исключением декомпрессии P / Invoke, которая, вероятно, в любом случае должна быть просто портирована на C #).
В идеале я бы не хотел добавлять другой слойTCP / IP, каналы и т. д. между моим кодом и клиентским Java-приложением, если я могу помочь (так что, вероятно, отсутствует WCF для Java-DeathStar на стороне Java).Я никогда не занимался серьезной разработкой с Java, но я горжусь тем, что библиотека в настоящее время является частью процесса интеграции для стороннего разработчика в его приложение (если, конечно, он работает на .NET:)), и я хотел бы иметь возможность сохранить ту же простоту использования для любых разработчиков Java, которые хотят того же опыта.
Так что, если у кого-то есть мнения по поводу трех предложенных мной вариантов (портировать на Java и поддерживать дважды, портировать на C и писать тонкие языковые привязки для .NET и Java или, попробовать и интегрировать Java и Mono), или любые другие предложения, которые я бы хотел услышать.
Спасибо
Редактировать: После разговора непосредственно с разработчиком на клиенте (т.е. удаление сломанного телефона отдела продаж AKA) требования изменились настолько, что этот вопрос уже не очень хорошо подходит для моей непосредственной ситуации. Однако я оставлю вопрос открытым в надежде, что мы сможем выработать еще несколько хороших предложений.
В моем конкретном случае клиент на самом деле работает на машинах с Windows в дополнение к Solaris (а кто нет?) И рад, что мы напишем приложение (служба Windows) поверх библиотеки и предоставим гораздо больше упрощенный и меньший API TCP / IP для них, чтобы кодировать против. Мы переведем их простые сообщения в формат, понятный нисходящей системе, и переведем входящие ответы обратно для их использования, чтобы они могли продолжать взаимодействовать с этой нисходящей системой через приложение Java.
Возвращаясь к исходному сценарию, подумав об этом пару недель, у меня есть еще несколько комментариев:
Переносная библиотека на основе C с различными языковыми привязками сверху, вероятно, была бы подходящим вариантом, если бы вы заранее знали, что вам потребуется поддержка нескольких языков / платформ.
В * nix, может ли один процесс одновременно выполнять как среду исполнения Java, так и среду Mono? Я знаю, что в более ранних версиях .NET у вас не было двух разных сред выполнения .NET в одном и том же процессе, но я думаю, что они исправили это в .NET 4? Если это возможно, как можно общаться между двумя? В идеале вам нужно что-то такое простое, как статический вызов метода и делегат для получения ответов.
Если нет простой прямой поддержки интерфейса между Java и Mono (методы, делегаты и т. Д.), Можно рассмотреть возможность использования чего-то вроде ZeroMQ с буфером протокола или Apache Thrift в качестве формата сообщения. Это будет работать внутри процесса, между процессами и по сети из-за поддержки ZeroMQ различных транспортов.