TL;DR Below
I'm working on a game server (in Java, but that part is less important), and have decided to split up the server logic from the engine logic; in part because they're in two different logical domains. The server will interact directly with the client, and handle the networking aspect of things, while the engine will deal with in-game events. I would like these to be as separate as possible, so that the engine doesn't deal with packets and networking, and the server doesn't deal with player movement, or game events. However, these two will have to remain coupled because, although they are in different domains, they are part of the same process.
For example, when the user launches their client and connects to the server, the server must send a message to the engine to create a new game session. The engine then initializes the world, adds the player to it, and registers the proper in-game event listeners. At this point, the engine tells the server that the world is ready. The server then sends a message client to load resources (images, landscape data, text, etc), registers packet handlers, and everything is ready to be played.
We also have to take it the other way. If the player disconnects their client, or logs out, then the server is the first to know of this state change. The server session may stay active, in case it's just a slight network hiccup, but eventually, it must tell the game engine to do any cleanup.
There can be many implementations of the engine and server. For example, they can be running in the same JVM instance, they could be on different instances, using socket channels to communicate between eachother, or we could have the engine on another server, using something like a REST service to communicate messages between them.
TL;DR
What sort of design patterns or strategies can I use to send messages between two coupled components, that should remain as separate as possible, without introducing an intermediary library?